From 95c4e57a9234f0ace8fe4c69ac17eff0e2faef56 Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Thu, 12 Feb 2026 15:33:53 +0800 Subject: [PATCH 01/14] unify DEFAULT_SHOW_FULL_NAME output in templates and dropdown --- templates/repo/search_name.tmpl | 2 +- web_src/js/features/repo-issue-list.ts | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/templates/repo/search_name.tmpl b/templates/repo/search_name.tmpl index 951f168866f6d..3616584af9f3c 100644 --- a/templates/repo/search_name.tmpl +++ b/templates/repo/search_name.tmpl @@ -1 +1 @@ -{{.Name}}{{if DefaultShowFullName}} {{.FullName}}{{end}} +{{if DefaultShowFullName}}{{.FullName}}{{else}}{{.Name}}{{end}} diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index 14f7d867b286b..f8423f8f6ca11 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -138,8 +138,9 @@ function initDropdownUserRemoteSearch(el: Element) { // the content is provided by backend IssuePosters handler processedResults.length = 0; for (const item of resp.results) { - let nameHtml = html`${item.username}`; - if (item.full_name) nameHtml += html`${item.full_name}`; + let nameHtml = html``; + nameHtml += item.full_name ? html`${item.full_name}` : item.username; + nameHtml += html``; if (selectedUsername.toLowerCase() === item.username.toLowerCase()) selectedUsername = item.username; processedResults.push({value: item.username, name: nameHtml}); } From 2e3fc1bf20e5743cef83d1e883139a4d8f64adef Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Thu, 12 Feb 2026 17:17:28 +0800 Subject: [PATCH 02/14] fix(user-search): only show full name if available --- templates/repo/search_name.tmpl | 2 +- web_src/js/features/repo-issue-list.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/search_name.tmpl b/templates/repo/search_name.tmpl index 3616584af9f3c..ad2c80397ef7a 100644 --- a/templates/repo/search_name.tmpl +++ b/templates/repo/search_name.tmpl @@ -1 +1 @@ -{{if DefaultShowFullName}}{{.FullName}}{{else}}{{.Name}}{{end}} +{{if and DefaultShowFullName .FullName}}{{.FullName}}{{else}}{{.Name}}{{end}} diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index f8423f8f6ca11..62fc8fccec333 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -139,7 +139,7 @@ function initDropdownUserRemoteSearch(el: Element) { processedResults.length = 0; for (const item of resp.results) { let nameHtml = html``; - nameHtml += item.full_name ? html`${item.full_name}` : item.username; + nameHtml += item.full_name ? html`${item.full_name}` : html`${item.username}`; nameHtml += html``; if (selectedUsername.toLowerCase() === item.username.toLowerCase()) selectedUsername = item.username; processedResults.push({value: item.username, name: nameHtml}); From f5c668a2c2411acc35789054f26867ae12d9e75e Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Fri, 13 Feb 2026 20:48:38 +0800 Subject: [PATCH 03/14] refactor(user-search): streamline full name display logic and remove unused CSS --- templates/repo/search_name.tmpl | 2 +- web_src/css/repo.css | 4 ---- web_src/js/features/repo-issue-list.ts | 6 +++--- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/templates/repo/search_name.tmpl b/templates/repo/search_name.tmpl index ad2c80397ef7a..6622aea335b11 100644 --- a/templates/repo/search_name.tmpl +++ b/templates/repo/search_name.tmpl @@ -1 +1 @@ -{{if and DefaultShowFullName .FullName}}{{.FullName}}{{else}}{{.Name}}{{end}} +{{if and DefaultShowFullName .FullName}}{{.FullName}}{{else}}{{.Name}}{{end}} diff --git a/web_src/css/repo.css b/web_src/css/repo.css index 83df3e5c2923f..c88dce9310ad6 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -1969,10 +1969,6 @@ tbody.commit-list { padding-right: 0.5em; /* To match the alignment with the "required" label */ } -.search-fullname { - color: var(--color-text-light-2); -} - #issue-pins { display: grid; grid-template-columns: repeat(3, 1fr); diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index 62fc8fccec333..327104a7f1f94 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -138,9 +138,9 @@ function initDropdownUserRemoteSearch(el: Element) { // the content is provided by backend IssuePosters handler processedResults.length = 0; for (const item of resp.results) { - let nameHtml = html``; - nameHtml += item.full_name ? html`${item.full_name}` : html`${item.username}`; - nameHtml += html``; + const avatarImg = ``; + const fullName = item.full_name ? item.full_name : item.username; + const nameHtml = html`${avatarImg}${fullName}`; if (selectedUsername.toLowerCase() === item.username.toLowerCase()) selectedUsername = item.username; processedResults.push({value: item.username, name: nameHtml}); } From bfb6bd026ad7ae910dfc25a35dbb38ed3edd0a8f Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Fri, 13 Feb 2026 21:06:06 +0800 Subject: [PATCH 04/14] fix(repo-issue-list): improve full name rendering in dropdown menu --- web_src/js/features/repo-issue-list.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index 327104a7f1f94..9c2803c9490cc 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -139,8 +139,8 @@ function initDropdownUserRemoteSearch(el: Element) { processedResults.length = 0; for (const item of resp.results) { const avatarImg = ``; - const fullName = item.full_name ? item.full_name : item.username; - const nameHtml = html`${avatarImg}${fullName}`; + const fullName = item.full_name ? html`${item.full_name}` : item.username; + const nameHtml = `${avatarImg}${fullName}`; if (selectedUsername.toLowerCase() === item.username.toLowerCase()) selectedUsername = item.username; processedResults.push({value: item.username, name: nameHtml}); } From c2e986bbecf1df7b5f5fc09136911b01a90c7900 Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Fri, 13 Feb 2026 21:14:40 +0800 Subject: [PATCH 05/14] Fix lint --- web_src/js/features/repo-issue-list.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index 9c2803c9490cc..c1891d93ea3d1 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -138,9 +138,7 @@ function initDropdownUserRemoteSearch(el: Element) { // the content is provided by backend IssuePosters handler processedResults.length = 0; for (const item of resp.results) { - const avatarImg = ``; - const fullName = item.full_name ? html`${item.full_name}` : item.username; - const nameHtml = `${avatarImg}${fullName}`; + const nameHtml = html`${item.full_name || item.username}`; if (selectedUsername.toLowerCase() === item.username.toLowerCase()) selectedUsername = item.username; processedResults.push({value: item.username, name: nameHtml}); } From ee48545fc459fe6b3458c81af196ae07514289e3 Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Wed, 4 Mar 2026 08:30:36 +0800 Subject: [PATCH 06/14] Add data-tooltip-content for better user experience --- templates/repo/search_name.tmpl | 2 +- web_src/js/features/repo-issue-list.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/repo/search_name.tmpl b/templates/repo/search_name.tmpl index 6622aea335b11..0f1c336ead215 100644 --- a/templates/repo/search_name.tmpl +++ b/templates/repo/search_name.tmpl @@ -1 +1 @@ -{{if and DefaultShowFullName .FullName}}{{.FullName}}{{else}}{{.Name}}{{end}} +{{if and DefaultShowFullName .FullName}}{{.FullName}}{{else}}{{.Name}}{{end}} diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index c1891d93ea3d1..ad2e54392d03d 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -138,7 +138,7 @@ function initDropdownUserRemoteSearch(el: Element) { // the content is provided by backend IssuePosters handler processedResults.length = 0; for (const item of resp.results) { - const nameHtml = html`${item.full_name || item.username}`; + const nameHtml = html`${item.full_name || item.username}`; if (selectedUsername.toLowerCase() === item.username.toLowerCase()) selectedUsername = item.username; processedResults.push({value: item.username, name: nameHtml}); } From 04c23ee17aea4b476dee96ac50fc91a9b3a112e5 Mon Sep 17 00:00:00 2001 From: Tyrone Yeh Date: Wed, 4 Mar 2026 10:19:00 +0800 Subject: [PATCH 07/14] Refactor search display to show full names. --- templates/repo/search_name.tmpl | 2 +- web_src/css/repo.css | 4 ++++ web_src/js/features/repo-issue-list.ts | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/templates/repo/search_name.tmpl b/templates/repo/search_name.tmpl index 0f1c336ead215..b0ae9ee11bebf 100644 --- a/templates/repo/search_name.tmpl +++ b/templates/repo/search_name.tmpl @@ -1 +1 @@ -{{if and DefaultShowFullName .FullName}}{{.FullName}}{{else}}{{.Name}}{{end}} +{{.Name}}{{if .FullName}} ({{.FullName}}){{end}} diff --git a/web_src/css/repo.css b/web_src/css/repo.css index c88dce9310ad6..83df3e5c2923f 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -1969,6 +1969,10 @@ tbody.commit-list { padding-right: 0.5em; /* To match the alignment with the "required" label */ } +.search-fullname { + color: var(--color-text-light-2); +} + #issue-pins { display: grid; grid-template-columns: repeat(3, 1fr); diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index ad2e54392d03d..0bff65a3d8241 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -138,7 +138,8 @@ function initDropdownUserRemoteSearch(el: Element) { // the content is provided by backend IssuePosters handler processedResults.length = 0; for (const item of resp.results) { - const nameHtml = html`${item.full_name || item.username}`; + let nameHtml = html`${item.username}`; + nameHtml += item.full_name ? html` (${item.full_name})` : ''; if (selectedUsername.toLowerCase() === item.username.toLowerCase()) selectedUsername = item.username; processedResults.push({value: item.username, name: nameHtml}); } From 9953a02cb5c261e4ea0679ef0348bd6103ee9064 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 4 Mar 2026 15:51:28 +0800 Subject: [PATCH 08/14] refactor --- models/user/user.go | 26 ++++++++++++++++---------- modules/setting/ui.go | 6 +++++- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/models/user/user.go b/models/user/user.go index 1797d3eefc2b5..b88f50cf6cc3e 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -416,16 +416,6 @@ func (u *User) IsTokenAccessAllowed() bool { return u.Type == UserTypeIndividual || u.Type == UserTypeBot } -// DisplayName returns full name if it's not empty, -// returns username otherwise. -func (u *User) DisplayName() string { - trimmed := strings.TrimSpace(u.FullName) - if len(trimmed) > 0 { - return trimmed - } - return u.Name -} - // EmailTo returns a string suitable to be put into a e-mail `To:` header. func (u *User) EmailTo() string { sanitizedDisplayName := globalVars().emailToReplacer.Replace(u.DisplayName()) @@ -444,6 +434,22 @@ func (u *User) EmailTo() string { return fmt.Sprintf("%s <%s>", mime.QEncoding.Encode("utf-8", add.Name), add.Address) } +// TODO: there are 4-5 methods to display a user's "name", need to refactor them +// * user.Name / user.FullName (DefaultShowFullName): directly used in templates +// * user.DisplayName(): always show FullName if it's not empty, otherwise show Name +// * user.GetDisplayName(): show FullName if it's not empty and DefaultShowFullName is set, otherwise show Name +// * user.GetCompleteName(): show "FullName (Name)" if FullName is not empty, otherwise show Name + +// DisplayName returns full name if it's not empty, +// returns username otherwise. +func (u *User) DisplayName() string { + trimmed := strings.TrimSpace(u.FullName) + if len(trimmed) > 0 { + return trimmed + } + return u.Name +} + // GetDisplayName returns full name if it's not empty and DEFAULT_SHOW_FULL_NAME is set, // returns username otherwise. func (u *User) GetDisplayName() string { diff --git a/modules/setting/ui.go b/modules/setting/ui.go index 77a5b45d0a02b..e8d09334151bd 100644 --- a/modules/setting/ui.go +++ b/modules/setting/ui.go @@ -25,7 +25,6 @@ var UI = struct { ReactionMaxUserNum int MaxDisplayFileSize int64 ShowUserEmail bool - DefaultShowFullName bool DefaultTheme string Themes []string FileIconTheme string @@ -43,6 +42,11 @@ var UI = struct { AmbiguousUnicodeDetection bool + // TODO: DefaultShowFullName is introduced by https://github.com/go-gitea/gitea/pull/6710 + // But that PR didn't do it right. For most cases, either "username" or "username (Full Name)" should be used. + // Only in very few cases (e.g.: unimportant lists, narrow layout), "username" or "Full Name" can be used. + DefaultShowFullName bool + Notification struct { MinTimeout time.Duration TimeoutStep time.Duration From 3acd0dcee486dfe27bbd8cab2068f3cf6f56ea36 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 4 Mar 2026 15:53:38 +0800 Subject: [PATCH 09/14] remove user.GetCompleteName() --- models/user/user.go | 12 ------------ services/mailer/mail.go | 13 +++++++++---- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/models/user/user.go b/models/user/user.go index b88f50cf6cc3e..b7f0d39cedcb1 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -438,7 +438,6 @@ func (u *User) EmailTo() string { // * user.Name / user.FullName (DefaultShowFullName): directly used in templates // * user.DisplayName(): always show FullName if it's not empty, otherwise show Name // * user.GetDisplayName(): show FullName if it's not empty and DefaultShowFullName is set, otherwise show Name -// * user.GetCompleteName(): show "FullName (Name)" if FullName is not empty, otherwise show Name // DisplayName returns full name if it's not empty, // returns username otherwise. @@ -462,17 +461,6 @@ func (u *User) GetDisplayName() string { return u.Name } -// GetCompleteName returns the full name and username in the form of -// "Full Name (username)" if full name is not empty, otherwise it returns -// "username". -func (u *User) GetCompleteName() string { - trimmedFullName := strings.TrimSpace(u.FullName) - if len(trimmedFullName) > 0 { - return fmt.Sprintf("%s (%s)", trimmedFullName, u.Name) - } - return u.Name -} - func gitSafeName(name string) string { return strings.TrimSpace(strings.NewReplacer("\n", "", "<", "", ">", "").Replace(name)) } diff --git a/services/mailer/mail.go b/services/mailer/mail.go index 8f831f89adbc9..a08ed71480c89 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -158,18 +158,23 @@ func (b64embedder *mailAttachmentBase64Embedder) AttachmentSrcToBase64DataURI(ct func fromDisplayName(u *user_model.User) string { if setting.MailService.FromDisplayNameFormatTemplate != nil { - var ctx bytes.Buffer - err := setting.MailService.FromDisplayNameFormatTemplate.Execute(&ctx, map[string]any{ + var buf bytes.Buffer + err := setting.MailService.FromDisplayNameFormatTemplate.Execute(&buf, map[string]any{ "DisplayName": u.DisplayName(), "AppName": setting.AppName, "Domain": setting.Domain, }) if err == nil { - return mime.QEncoding.Encode("utf-8", ctx.String()) + return mime.QEncoding.Encode("utf-8", buf.String()) } log.Error("fromDisplayName: %w", err) } - return u.GetCompleteName() + def := u.Name + if fullName := strings.TrimSpace(u.FullName); fullName != "" { + // use "Full Name (username)" for email's sender name if Full Name is not empty + def = fullName + " (" + u.Name + ")" + } + return def } func generateMetadataHeaders(repo *repo_model.Repository) map[string]string { From c181fa7ae99b342eca5b168fbf2cda44ac12ecc6 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 4 Mar 2026 18:42:59 +0800 Subject: [PATCH 10/14] clean up DefaultShowFullName --- models/repo/user_repo.go | 6 +-- models/repo/user_repo_test.go | 4 +- models/user/user.go | 45 +++++++++++++---------- modules/templates/helper.go | 3 -- routers/web/repo/issue_content_history.go | 11 +++--- routers/web/repo/issue_poster.go | 7 +--- templates/admin/org/list.tmpl | 7 +++- templates/repo/commits_list.tmpl | 12 +++--- templates/repo/graph/commits.tmpl | 11 ++---- templates/repo/latest_commit.tmpl | 16 +++----- templates/repo/search_name.tmpl | 2 +- web_src/css/repo.css | 8 +++- web_src/js/features/repo-issue-list.ts | 9 +++-- 13 files changed, 70 insertions(+), 71 deletions(-) diff --git a/models/repo/user_repo.go b/models/repo/user_repo.go index 232087d86594e..bb67e8be2688a 100644 --- a/models/repo/user_repo.go +++ b/models/repo/user_repo.go @@ -148,12 +148,10 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us // GetIssuePostersWithSearch returns users with limit of 30 whose username started with prefix that have authored an issue/pull request for the given repository // If isShowFullName is set to true, also include full name prefix search -func GetIssuePostersWithSearch(ctx context.Context, repo *Repository, isPull bool, search string, isShowFullName bool) ([]*user_model.User, error) { +func GetIssuePostersWithSearch(ctx context.Context, repo *Repository, isPull bool, search string) ([]*user_model.User, error) { users := make([]*user_model.User, 0, 30) var prefixCond builder.Cond = builder.Like{"lower_name", strings.ToLower(search) + "%"} - if isShowFullName { - prefixCond = prefixCond.Or(db.BuildCaseInsensitiveLike("full_name", "%"+search+"%")) - } + prefixCond = prefixCond.Or(db.BuildCaseInsensitiveLike("full_name", "%"+search+"%")) cond := builder.In("`user`.id", builder.Select("poster_id").From("issue").Where( diff --git a/models/repo/user_repo_test.go b/models/repo/user_repo_test.go index a53cf39dc4cfb..cd8a0f1a1f77e 100644 --- a/models/repo/user_repo_test.go +++ b/models/repo/user_repo_test.go @@ -44,12 +44,12 @@ func TestGetIssuePostersWithSearch(t *testing.T) { repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) - users, err := repo_model.GetIssuePostersWithSearch(t.Context(), repo2, false, "USER", false /* full name */) + users, err := repo_model.GetIssuePostersWithSearch(t.Context(), repo2, false, "USER") require.NoError(t, err) require.Len(t, users, 1) assert.Equal(t, "user2", users[0].Name) - users, err = repo_model.GetIssuePostersWithSearch(t.Context(), repo2, false, "TW%O", true /* full name */) + users, err = repo_model.GetIssuePostersWithSearch(t.Context(), repo2, false, "TW%O") require.NoError(t, err) require.Len(t, users, 1) assert.Equal(t, "user2", users[0].Name) diff --git a/models/user/user.go b/models/user/user.go index b7f0d39cedcb1..f06622466d9b9 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -8,6 +8,7 @@ import ( "context" "encoding/hex" "fmt" + "html/template" "mime" "net/mail" "net/url" @@ -27,6 +28,7 @@ import ( "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/htmlutil" "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/optional" @@ -434,33 +436,46 @@ func (u *User) EmailTo() string { return fmt.Sprintf("%s <%s>", mime.QEncoding.Encode("utf-8", add.Name), add.Address) } -// TODO: there are 4-5 methods to display a user's "name", need to refactor them +// TODO: there are already too many methods to display a user's "name", need to refactor them // * user.Name / user.FullName (DefaultShowFullName): directly used in templates // * user.DisplayName(): always show FullName if it's not empty, otherwise show Name // * user.GetDisplayName(): show FullName if it's not empty and DefaultShowFullName is set, otherwise show Name -// DisplayName returns full name if it's not empty, -// returns username otherwise. +// DisplayName returns full name if it's not empty, returns username otherwise. func (u *User) DisplayName() string { - trimmed := strings.TrimSpace(u.FullName) - if len(trimmed) > 0 { - return trimmed + fullName := strings.TrimSpace(u.FullName) + if fullName != "" { + return fullName } return u.Name } -// GetDisplayName returns full name if it's not empty and DEFAULT_SHOW_FULL_NAME is set, -// returns username otherwise. +// GetDisplayName returns full name if it's not empty and DEFAULT_SHOW_FULL_NAME is set, otherwise, username. func (u *User) GetDisplayName() string { if setting.UI.DefaultShowFullName { - trimmed := strings.TrimSpace(u.FullName) - if len(trimmed) > 0 { - return trimmed + fullName := strings.TrimSpace(u.FullName) + if fullName != "" { + return fullName } } return u.Name } +// ShortName ellipses username to length (still used by many templates), it calls GetDisplayName and respects DEFAULT_SHOW_FULL_NAME +func (u *User) ShortName(length int) string { + return util.EllipsisDisplayString(u.GetDisplayName(), length) +} + +func (u *User) GetShortDisplayNameLinkHTML() template.HTML { + displayName, displayTooltip := u.Name, u.FullName + if setting.UI.DefaultShowFullName { + if fullName := strings.TrimSpace(u.FullName); fullName != "" { + displayName, displayTooltip = fullName, u.Name + } + } + return htmlutil.HTMLFormat(`%s`, u.HomeLink(), displayTooltip, displayName) +} + func gitSafeName(name string) string { return strings.TrimSpace(strings.NewReplacer("\n", "", "<", "", ">", "").Replace(name)) } @@ -481,14 +496,6 @@ func (u *User) GitName() string { return fmt.Sprintf("user-%d", u.ID) } -// ShortName ellipses username to length -func (u *User) ShortName(length int) string { - if setting.UI.DefaultShowFullName && len(u.FullName) > 0 { - return util.EllipsisDisplayString(u.FullName, length) - } - return util.EllipsisDisplayString(u.Name, length) -} - // IsMailable checks if a user is eligible // to receive emails. func (u *User) IsMailable() bool { diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 11c52bd5a7f9d..82087568dfda9 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -96,9 +96,6 @@ func NewFuncMap() template.FuncMap { "AssetVersion": func() string { return setting.AssetVersion }, - "DefaultShowFullName": func() bool { - return setting.UI.DefaultShowFullName - }, "ShowFooterTemplateLoadTime": func() bool { return setting.Other.ShowFooterTemplateLoadTime }, diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index a56df78163d38..44bebf2f90650 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -12,7 +12,6 @@ import ( "code.gitea.io/gitea/models/avatars" issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/log" - "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/services/context" @@ -63,15 +62,15 @@ func GetContentHistoryList(ctx *context.Context) { actionText = ctx.Locale.TrString("repo.issues.content_history.edited") } - username := item.UserName - if setting.UI.DefaultShowFullName && strings.TrimSpace(item.UserFullName) != "" { - username = strings.TrimSpace(item.UserFullName) + displayName := item.UserName + if fullName := strings.TrimSpace(item.UserFullName); fullName != "" { + displayName += " (" + fullName + ")" } src := html.EscapeString(item.UserAvatarLink) class := avatars.DefaultAvatarClass + " tw-mr-2" - name := html.EscapeString(username) - avatarHTML := string(templates.AvatarHTML(src, 28, class, username)) + name := html.EscapeString(displayName) + avatarHTML := string(templates.AvatarHTML(src, 28, class, displayName)) timeSinceHTML := string(templates.TimeSince(item.EditedUnix)) results = append(results, map[string]any{ diff --git a/routers/web/repo/issue_poster.go b/routers/web/repo/issue_poster.go index 07059b9b7bfc3..4f00f40a91f3f 100644 --- a/routers/web/repo/issue_poster.go +++ b/routers/web/repo/issue_poster.go @@ -10,7 +10,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/setting" shared_user "code.gitea.io/gitea/routers/web/shared/user" "code.gitea.io/gitea/services/context" ) @@ -34,7 +33,7 @@ func IssuePullPosters(ctx *context.Context) { func issuePosters(ctx *context.Context, isPullList bool) { repo := ctx.Repo.Repository search := strings.TrimSpace(ctx.FormString("q")) - posters, err := repo_model.GetIssuePostersWithSearch(ctx, repo, isPullList, search, setting.UI.DefaultShowFullName) + posters, err := repo_model.GetIssuePostersWithSearch(ctx, repo, isPullList, search) if err != nil { ctx.JSON(http.StatusInternalServerError, err) return @@ -54,9 +53,7 @@ func issuePosters(ctx *context.Context, isPullList bool) { resp.Results = make([]*userSearchInfo, len(posters)) for i, user := range posters { resp.Results[i] = &userSearchInfo{UserID: user.ID, UserName: user.Name, AvatarLink: user.AvatarLink(ctx)} - if setting.UI.DefaultShowFullName { - resp.Results[i].FullName = user.FullName - } + resp.Results[i].FullName = user.FullName } ctx.JSON(http.StatusOK, resp) } diff --git a/templates/admin/org/list.tmpl b/templates/admin/org/list.tmpl index c2c0280e4cd52..22f888074923b 100644 --- a/templates/admin/org/list.tmpl +++ b/templates/admin/org/list.tmpl @@ -48,11 +48,14 @@ - {{range .Users}} + {{range $org := .Users}} {{.ID}} - {{if and DefaultShowFullName .FullName}}{{.FullName}} ({{.Name}}){{else}}{{.Name}}{{end}} + + {{$org.Name}} + {{if $org.FullName}}({{$org.FullName}}){{end}} + {{if .Visibility.IsPrivate}} {{svg "octicon-lock"}} {{end}} diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl index 1a236582a26dd..f1e9a90c3e16d 100644 --- a/templates/repo/commits_list.tmpl +++ b/templates/repo/commits_list.tmpl @@ -14,18 +14,16 @@ {{range .Commits}} -
+ {{$userName := .Author.Name}} {{if .User}} - {{if and .User.FullName DefaultShowFullName}} - {{$userName = .User.FullName}} - {{end}} - {{ctx.AvatarUtils.Avatar .User 28 "tw-mr-2"}}{{$userName}} + {{ctx.AvatarUtils.Avatar .User 28 "tw-mr-2"}} + {{.User.GetShortDisplayNameLinkHTML}} {{else}} {{ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name 28 "tw-mr-2"}} - {{$userName}} + {{$userName}} {{end}} -
+ {{$commitBaseLink := ""}} diff --git a/templates/repo/graph/commits.tmpl b/templates/repo/graph/commits.tmpl index d92be9c5ed1ca..d86f73fe65413 100644 --- a/templates/repo/graph/commits.tmpl +++ b/templates/repo/graph/commits.tmpl @@ -41,16 +41,13 @@ - {{$userName := $commit.Commit.Author.Name}} {{if $commit.User}} - {{if and $commit.User.FullName DefaultShowFullName}} - {{$userName = $commit.User.FullName}} - {{end}} {{ctx.AvatarUtils.Avatar $commit.User 18}} - {{$userName}} + {{$commit.User.GetShortDisplayNameLinkHTML}} {{else}} - {{ctx.AvatarUtils.AvatarByEmail $commit.Commit.Author.Email $userName 18}} - {{$userName}} + {{$gitUserName := $commit.Commit.Author.Name}} + {{ctx.AvatarUtils.AvatarByEmail $commit.Commit.Author.Email $gitUserName 18}} + {{$gitUserName}} {{end}} diff --git a/templates/repo/latest_commit.tmpl b/templates/repo/latest_commit.tmpl index cff338949f219..71209a262fbf4 100644 --- a/templates/repo/latest_commit.tmpl +++ b/templates/repo/latest_commit.tmpl @@ -2,19 +2,15 @@ {{if not .LatestCommit}} … {{else}} + {{if .LatestCommitUser}} {{ctx.AvatarUtils.Avatar .LatestCommitUser 24}} - {{if and .LatestCommitUser.FullName DefaultShowFullName}} - {{.LatestCommitUser.FullName}} - {{else}} - {{if .LatestCommit.Author}}{{.LatestCommit.Author.Name}}{{else}}{{.LatestCommitUser.Name}}{{end}} - {{end}} - {{else}} - {{if .LatestCommit.Author}} - {{ctx.AvatarUtils.AvatarByEmail .LatestCommit.Author.Email .LatestCommit.Author.Name 24}} - {{.LatestCommit.Author.Name}} - {{end}} + {{.LatestCommitUser.GetShortDisplayNameLinkHTML}} + {{else if .LatestCommit.Author}} + {{ctx.AvatarUtils.AvatarByEmail .LatestCommit.Author.Email .LatestCommit.Author.Name 24}} + {{.LatestCommit.Author.Name}} {{end}} + {{template "repo/commit_sign_badge" dict "Commit" .LatestCommit "CommitBaseLink" (print .RepoLink "/commit") "CommitSignVerification" .LatestCommitVerification}} diff --git a/templates/repo/search_name.tmpl b/templates/repo/search_name.tmpl index b0ae9ee11bebf..c9dcccb265a93 100644 --- a/templates/repo/search_name.tmpl +++ b/templates/repo/search_name.tmpl @@ -1 +1 @@ -{{.Name}}{{if .FullName}} ({{.FullName}}){{end}} +{{.Name}} {{if .FullName}}({{.FullName}}){{end}} diff --git a/web_src/css/repo.css b/web_src/css/repo.css index 83df3e5c2923f..ea825f57a72b8 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -1969,7 +1969,13 @@ tbody.commit-list { padding-right: 0.5em; /* To match the alignment with the "required" label */ } -.search-fullname { +.username-display { + display: inline-flex; + gap: var(--gap-inline); + align-items: center; +} + +.username-display > .username-fullname { color: var(--color-text-light-2); } diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index 0bff65a3d8241..36f965f41f6c4 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -1,6 +1,6 @@ import {updateIssuesMeta} from './repo-common.ts'; import {toggleElem, queryElems, isElemVisible} from '../utils/dom.ts'; -import {html} from '../utils/html.ts'; +import {html, htmlRaw} from '../utils/html.ts'; import {confirmModal} from './comp/ConfirmModal.ts'; import {showErrorToast} from '../modules/toast.ts'; import {createSortable} from '../modules/sortable.ts'; @@ -138,10 +138,11 @@ function initDropdownUserRemoteSearch(el: Element) { // the content is provided by backend IssuePosters handler processedResults.length = 0; for (const item of resp.results) { - let nameHtml = html`${item.username}`; - nameHtml += item.full_name ? html` (${item.full_name})` : ''; + const htmlAvatar = html``; + const htmlFullName = item.full_name ? html`(${item.full_name})` : ''; + const htmlItem = html`${htmlRaw(htmlAvatar)}${item.username}${htmlRaw(htmlFullName)}`; if (selectedUsername.toLowerCase() === item.username.toLowerCase()) selectedUsername = item.username; - processedResults.push({value: item.username, name: nameHtml}); + processedResults.push({value: item.username, name: htmlItem}); } resp.results = processedResults; return resp; From 102bb3452a3172a19da29b1577388cfc93e5d09e Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 4 Mar 2026 19:06:13 +0800 Subject: [PATCH 11/14] clean up legacy code --- modules/templates/util_avatar.go | 9 +++----- routers/web/repo/issue_content_history.go | 27 ++++++++++------------- 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/modules/templates/util_avatar.go b/modules/templates/util_avatar.go index ee9994ab0b887..524c64d0b6e85 100644 --- a/modules/templates/util_avatar.go +++ b/modules/templates/util_avatar.go @@ -16,6 +16,7 @@ import ( user_model "code.gitea.io/gitea/models/user" gitea_html "code.gitea.io/gitea/modules/htmlutil" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/util" ) type AvatarUtils struct { @@ -29,13 +30,9 @@ func NewAvatarUtils(ctx context.Context) *AvatarUtils { // AvatarHTML creates the HTML for an avatar func AvatarHTML(src string, size int, class, name string) template.HTML { sizeStr := strconv.Itoa(size) - - if name == "" { - name = "avatar" - } - + name = util.IfZero(name, "avatar") // use empty alt, otherwise if the image fails to load, the width will follow the "alt" text's width - return template.HTML(``) + return template.HTML(``) } // Avatar renders user avatars. args: user, size (int), class (string) diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index 44bebf2f90650..0b71e8dc6dd3a 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -6,11 +6,13 @@ package repo import ( "bytes" "html" + "html/template" "net/http" "strings" "code.gitea.io/gitea/models/avatars" issues_model "code.gitea.io/gitea/models/issues" + "code.gitea.io/gitea/modules/htmlutil" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/services/context" @@ -52,29 +54,24 @@ func GetContentHistoryList(ctx *context.Context) { // value is historyId var results []map[string]any for _, item := range items { - var actionText string + var actionText template.HTML if item.IsDeleted { - actionTextDeleted := ctx.Locale.TrString("repo.issues.content_history.deleted") - actionText = "" + actionTextDeleted + "" + actionText = htmlutil.HTMLFormat(`%s`, ctx.Locale.TrString("repo.issues.content_history.deleted")) } else if item.IsFirstCreated { - actionText = ctx.Locale.TrString("repo.issues.content_history.created") + actionText = ctx.Locale.Tr("repo.issues.content_history.created") } else { - actionText = ctx.Locale.TrString("repo.issues.content_history.edited") + actionText = ctx.Locale.Tr("repo.issues.content_history.edited") } - displayName := item.UserName - if fullName := strings.TrimSpace(item.UserFullName); fullName != "" { - displayName += " (" + fullName + ")" + userName, fullNamePart := item.UserName, strings.TrimSpace(item.UserFullName) + if fullNamePart != "" { + fullNamePart = " (" + fullNamePart + ")" } - src := html.EscapeString(item.UserAvatarLink) - class := avatars.DefaultAvatarClass + " tw-mr-2" - name := html.EscapeString(displayName) - avatarHTML := string(templates.AvatarHTML(src, 28, class, displayName)) - timeSinceHTML := string(templates.TimeSince(item.EditedUnix)) - + avatarHTML := templates.AvatarHTML(item.UserAvatarLink, 24, avatars.DefaultAvatarClass+" tw-mr-2", userName) + timeSinceHTML := templates.TimeSince(item.EditedUnix) results = append(results, map[string]any{ - "name": avatarHTML + "" + name + " " + actionText + " " + timeSinceHTML, + "name": htmlutil.HTMLFormat("%s %s%s %s %s", avatarHTML, userName, fullNamePart, actionText, timeSinceHTML), "value": item.HistoryID, }) } From e093d592f53db11f77a21ae4a76151ca5381a85b Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 4 Mar 2026 19:12:15 +0800 Subject: [PATCH 12/14] clean up --- models/user/user.go | 9 ++++----- templates/repo/commits_list.tmpl | 3 +-- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/models/user/user.go b/models/user/user.go index d7c457ed6b45e..b02b9301daf77 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -468,11 +468,10 @@ func (u *User) ShortName(length int) string { } func (u *User) GetShortDisplayNameLinkHTML() template.HTML { - displayName, displayTooltip := u.Name, u.FullName - if setting.UI.DefaultShowFullName { - if fullName := strings.TrimSpace(u.FullName); fullName != "" { - displayName, displayTooltip = fullName, u.Name - } + fullName := strings.TrimSpace(u.FullName) + displayName, displayTooltip := u.Name, fullName + if setting.UI.DefaultShowFullName && fullName != "" { + displayName, displayTooltip = fullName, u.Name } return htmlutil.HTMLFormat(`%s`, u.HomeLink(), displayTooltip, displayName) } diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl index f1e9a90c3e16d..4e63e54ef4c4a 100644 --- a/templates/repo/commits_list.tmpl +++ b/templates/repo/commits_list.tmpl @@ -15,13 +15,12 @@ - {{$userName := .Author.Name}} {{if .User}} {{ctx.AvatarUtils.Avatar .User 28 "tw-mr-2"}} {{.User.GetShortDisplayNameLinkHTML}} {{else}} {{ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name 28 "tw-mr-2"}} - {{$userName}} + {{.Author.Name}} {{end}} From 9b4be7845c52f689ba1ea74c27ffdcd427278369 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 4 Mar 2026 19:53:10 +0800 Subject: [PATCH 13/14] fine tune --- models/repo/user_repo.go | 2 +- templates/repo/commits_list.tmpl | 14 +++++++------- templates/repo/latest_commit.tmpl | 10 +++++----- templates/repo/search_name.tmpl | 2 +- tests/integration/repo_commits_test.go | 11 +++++------ web_src/css/repo.css | 1 + web_src/js/features/repo-issue-list.ts | 4 ++-- 7 files changed, 22 insertions(+), 22 deletions(-) diff --git a/models/repo/user_repo.go b/models/repo/user_repo.go index 435c78be3906b..e15a64b01e8bc 100644 --- a/models/repo/user_repo.go +++ b/models/repo/user_repo.go @@ -147,7 +147,7 @@ func GetRepoAssignees(ctx context.Context, repo *Repository) (_ []*user_model.Us } // GetIssuePostersWithSearch returns users with limit of 30 whose username started with prefix that have authored an issue/pull request for the given repository -// If isShowFullName is set to true, also include full name prefix search +// It searches with the "user.name" and "user.full_name" fields case-insensitively. func GetIssuePostersWithSearch(ctx context.Context, repo *Repository, isPull bool, search string) ([]*user_model.User, error) { users := make([]*user_model.User, 0, 30) diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl index 4e63e54ef4c4a..a0722307a7011 100644 --- a/templates/repo/commits_list.tmpl +++ b/templates/repo/commits_list.tmpl @@ -15,13 +15,13 @@ - {{if .User}} - {{ctx.AvatarUtils.Avatar .User 28 "tw-mr-2"}} - {{.User.GetShortDisplayNameLinkHTML}} - {{else}} - {{ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name 28 "tw-mr-2"}} - {{.Author.Name}} - {{end}} + {{- if .User -}} + {{- ctx.AvatarUtils.Avatar .User 20 "tw-mr-2" -}} + {{- .User.GetShortDisplayNameLinkHTML -}} + {{- else -}} + {{- ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name 20 "tw-mr-2" -}} + {{- .Author.Name -}} + {{- end -}} diff --git a/templates/repo/latest_commit.tmpl b/templates/repo/latest_commit.tmpl index 71209a262fbf4..c8f1ad54928ce 100644 --- a/templates/repo/latest_commit.tmpl +++ b/templates/repo/latest_commit.tmpl @@ -3,13 +3,13 @@ … {{else}} - {{if .LatestCommitUser}} - {{ctx.AvatarUtils.Avatar .LatestCommitUser 24}} + {{- if .LatestCommitUser -}} + {{- ctx.AvatarUtils.Avatar .LatestCommitUser 20 "tw-mr-2" -}} {{.LatestCommitUser.GetShortDisplayNameLinkHTML}} - {{else if .LatestCommit.Author}} - {{ctx.AvatarUtils.AvatarByEmail .LatestCommit.Author.Email .LatestCommit.Author.Name 24}} + {{- else if .LatestCommit.Author -}} + {{- ctx.AvatarUtils.AvatarByEmail .LatestCommit.Author.Email .LatestCommit.Author.Name 20 "tw-mr-2" -}} {{.LatestCommit.Author.Name}} - {{end}} + {{- end -}} {{template "repo/commit_sign_badge" dict "Commit" .LatestCommit "CommitBaseLink" (print .RepoLink "/commit") "CommitSignVerification" .LatestCommitVerification}} diff --git a/templates/repo/search_name.tmpl b/templates/repo/search_name.tmpl index c9dcccb265a93..636c83330f204 100644 --- a/templates/repo/search_name.tmpl +++ b/templates/repo/search_name.tmpl @@ -1 +1 @@ -{{.Name}} {{if .FullName}}({{.FullName}}){{end}} +{{.Name}} {{if .FullName}}({{.FullName}}){{end}} diff --git a/tests/integration/repo_commits_test.go b/tests/integration/repo_commits_test.go index 461af0db64bd6..3bcea83f43829 100644 --- a/tests/integration/repo_commits_test.go +++ b/tests/integration/repo_commits_test.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "path" + "strings" "sync" "testing" @@ -37,7 +38,7 @@ func TestRepoCommits(t *testing.T) { doc.doc.Find("#commits-table .commit-id-short").Each(func(i int, s *goquery.Selection) { commits = append(commits, path.Base(s.AttrOr("href", ""))) }) - doc.doc.Find("#commits-table .author-wrapper").Each(func(i int, s *goquery.Selection) { + doc.doc.Find("#commits-table .author-wrapper a").Each(func(i int, s *goquery.Selection) { userHrefs = append(userHrefs, s.AttrOr("href", "")) }) assert.Equal(t, []string{"69554a64c1e6030f051e5c3f94bfbd773cd6a324", "27566bd5738fc8b4e3fef3c5e72cce608537bd95", "5099b81332712fe655e34e8dd63574f503f61811"}, commits) @@ -49,7 +50,7 @@ func TestRepoCommits(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body) commitHref := doc.doc.Find(".latest-commit .commit-id-short").AttrOr("href", "") - authorHref := doc.doc.Find(".latest-commit .author-wrapper").AttrOr("href", "") + authorHref := doc.doc.Find(".latest-commit .author-wrapper a").AttrOr("href", "") assert.Equal(t, "/user2/repo16/commit/69554a64c1e6030f051e5c3f94bfbd773cd6a324", commitHref) assert.Equal(t, "/user2", authorHref) }) @@ -65,8 +66,7 @@ func TestRepoCommits(t *testing.T) { commitHref := doc.doc.Find("#commits-table tr:first-child .commit-id-short").AttrOr("href", "") assert.Equal(t, "/user2/repo1/commit/985f0301dba5e7b34be866819cd15ad3d8f508ee", commitHref) authorElem := doc.doc.Find("#commits-table tr:first-child .author-wrapper") - assert.Equal(t, "6543", authorElem.Text()) - assert.Equal(t, "span", authorElem.Nodes[0].Data) + assert.Equal(t, "6543", strings.TrimSpace(authorElem.Text())) }) t.Run("LastCommitNonExistingCommiter", func(t *testing.T) { @@ -76,8 +76,7 @@ func TestRepoCommits(t *testing.T) { commitHref := doc.doc.Find(".latest-commit .commit-id-short").AttrOr("href", "") assert.Equal(t, "/user2/repo1/commit/985f0301dba5e7b34be866819cd15ad3d8f508ee", commitHref) authorElem := doc.doc.Find(".latest-commit .author-wrapper") - assert.Equal(t, "6543", authorElem.Text()) - assert.Equal(t, "span", authorElem.Nodes[0].Data) + assert.Equal(t, "6543", strings.TrimSpace(authorElem.Text())) }) } diff --git a/web_src/css/repo.css b/web_src/css/repo.css index ea825f57a72b8..f4198408994ec 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -1970,6 +1970,7 @@ tbody.commit-list { } .username-display { + max-width: 100%; /* the inner part might have "gt-ellipsis" */ display: inline-flex; gap: var(--gap-inline); align-items: center; diff --git a/web_src/js/features/repo-issue-list.ts b/web_src/js/features/repo-issue-list.ts index 36f965f41f6c4..c0cd3c7f22c6b 100644 --- a/web_src/js/features/repo-issue-list.ts +++ b/web_src/js/features/repo-issue-list.ts @@ -139,8 +139,8 @@ function initDropdownUserRemoteSearch(el: Element) { processedResults.length = 0; for (const item of resp.results) { const htmlAvatar = html``; - const htmlFullName = item.full_name ? html`(${item.full_name})` : ''; - const htmlItem = html`${htmlRaw(htmlAvatar)}${item.username}${htmlRaw(htmlFullName)}`; + const htmlFullName = item.full_name ? html`(${item.full_name})` : ''; + const htmlItem = html`${htmlRaw(htmlAvatar)}${item.username}${htmlRaw(htmlFullName)}`; if (selectedUsername.toLowerCase() === item.username.toLowerCase()) selectedUsername = item.username; processedResults.push({value: item.username, name: htmlItem}); } From 8bb9cf1dd0edb89395285b5e5ce55f0d5c6679a5 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Wed, 4 Mar 2026 20:03:34 +0800 Subject: [PATCH 14/14] fine tune --- models/user/user.go | 6 ++++-- modules/setting/ui.go | 6 +++++- routers/web/repo/issue_content_history.go | 17 +++++++++-------- .../repo/issue/filter_item_user_assign.tmpl | 2 +- web_src/css/repo.css | 1 + 5 files changed, 20 insertions(+), 12 deletions(-) diff --git a/models/user/user.go b/models/user/user.go index b02b9301daf77..a74662bb12ab6 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -437,10 +437,12 @@ func (u *User) EmailTo() string { return fmt.Sprintf("%s <%s>", mime.QEncoding.Encode("utf-8", add.Name), add.Address) } -// TODO: there are already too many methods to display a user's "name", need to refactor them -// * user.Name / user.FullName (DefaultShowFullName): directly used in templates +// TODO: DefaultShowFullName causes messy logic, there are already too many methods to display a user's "display name", need to refactor them +// * user.Name / user.FullName: directly used in templates // * user.DisplayName(): always show FullName if it's not empty, otherwise show Name // * user.GetDisplayName(): show FullName if it's not empty and DefaultShowFullName is set, otherwise show Name +// * user.ShortName(): used a lot in templates, but it should be removed and let frontend use "ellipsis" styles +// * activity action.ShortActUserName/GetActDisplayName/GetActDisplayNameTitle, etc: duplicate and messy // DisplayName returns full name if it's not empty, returns username otherwise. func (u *User) DisplayName() string { diff --git a/modules/setting/ui.go b/modules/setting/ui.go index e8d09334151bd..722341a71eaaa 100644 --- a/modules/setting/ui.go +++ b/modules/setting/ui.go @@ -43,7 +43,11 @@ var UI = struct { AmbiguousUnicodeDetection bool // TODO: DefaultShowFullName is introduced by https://github.com/go-gitea/gitea/pull/6710 - // But that PR didn't do it right. For most cases, either "username" or "username (Full Name)" should be used. + // But there are still many edge cases: + // * Many places still use "username", not respecting this setting + // * Many places use "Full Name" if it is not empty, cause inconsistent UI for users who have set their full name but some others don't + // * Even if DefaultShowFullName=false, many places still need to show the full name + // For most cases, either "username" or "username (Full Name)" should be used and are good enough. // Only in very few cases (e.g.: unimportant lists, narrow layout), "username" or "Full Name" can be used. DefaultShowFullName bool diff --git a/routers/web/repo/issue_content_history.go b/routers/web/repo/issue_content_history.go index 0b71e8dc6dd3a..23cedfcb80a3c 100644 --- a/routers/web/repo/issue_content_history.go +++ b/routers/web/repo/issue_content_history.go @@ -54,24 +54,25 @@ func GetContentHistoryList(ctx *context.Context) { // value is historyId var results []map[string]any for _, item := range items { - var actionText template.HTML + var actionHTML template.HTML if item.IsDeleted { - actionText = htmlutil.HTMLFormat(`%s`, ctx.Locale.TrString("repo.issues.content_history.deleted")) + actionHTML = htmlutil.HTMLFormat(`%s`, ctx.Locale.TrString("repo.issues.content_history.deleted")) } else if item.IsFirstCreated { - actionText = ctx.Locale.Tr("repo.issues.content_history.created") + actionHTML = ctx.Locale.Tr("repo.issues.content_history.created") } else { - actionText = ctx.Locale.Tr("repo.issues.content_history.edited") + actionHTML = ctx.Locale.Tr("repo.issues.content_history.edited") } - userName, fullNamePart := item.UserName, strings.TrimSpace(item.UserFullName) - if fullNamePart != "" { - fullNamePart = " (" + fullNamePart + ")" + var fullNameHTML template.HTML + userName, fullName := item.UserName, strings.TrimSpace(item.UserFullName) + if fullName != "" { + fullNameHTML = htmlutil.HTMLFormat(` (%s)`, fullName) } avatarHTML := templates.AvatarHTML(item.UserAvatarLink, 24, avatars.DefaultAvatarClass+" tw-mr-2", userName) timeSinceHTML := templates.TimeSince(item.EditedUnix) results = append(results, map[string]any{ - "name": htmlutil.HTMLFormat("%s %s%s %s %s", avatarHTML, userName, fullNamePart, actionText, timeSinceHTML), + "name": htmlutil.HTMLFormat("%s %s%s %s %s", avatarHTML, userName, fullNameHTML, actionHTML, timeSinceHTML), "value": item.HistoryID, }) } diff --git a/templates/repo/issue/filter_item_user_assign.tmpl b/templates/repo/issue/filter_item_user_assign.tmpl index 42886edaa06d8..5ca8a8079c2b3 100644 --- a/templates/repo/issue/filter_item_user_assign.tmpl +++ b/templates/repo/issue/filter_item_user_assign.tmpl @@ -10,7 +10,7 @@ {{$queryLink := .QueryLink}}