From cc129d2ca22100fe9c28106d9bc302678651f339 Mon Sep 17 00:00:00 2001 From: silverwind Date: Wed, 15 Dec 2021 18:18:38 -0800 Subject: [PATCH] Make AvatarRenderedSizeFactor configurable and set it to 3 (#17951) Save a bit of bandwidth by only requesting 3-times the rendered avatar size. Factor 4 is only really beneficial on a handful of mobile phones and I don't think they are the primary device we design for. Configurability contributed by zeripath. Fixes: https://github.com/go-gitea/gitea/pull/17422 Fixes: https://github.com/go-gitea/gitea/issues/16287 Co-authored-by: wxiaoguang --- custom/conf/app.example.ini | 4 ++++ .../doc/advanced/config-cheat-sheet.en-us.md | 1 + models/avatars/avatar.go | 3 --- modules/repository/commits.go | 3 ++- modules/repository/commits_test.go | 4 ++-- modules/setting/picture.go | 15 +++++++++------ modules/templates/helper.go | 8 ++++---- 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 2ade90799..1d19a3438 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -1587,6 +1587,10 @@ PATH = ;AVATAR_MAX_WIDTH = 4096 ;AVATAR_MAX_HEIGHT = 3072 ;; +;; The multiplication factor for rendered avatar images. +;; Larger values result in finer rendering on HiDPI devices. +;AVATAR_RENDERED_SIZE_FACTOR = 3 +;; ;; Maximum allowed file size for uploaded avatars. ;; This is to limit the amount of RAM used when resizing the image. ;AVATAR_MAX_FILE_SIZE = 1048576 diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index e2a2687fa..07655a181 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -710,6 +710,7 @@ Define allowed algorithms and their minimum key length (use -1 to disable a type - `AVATAR_MAX_WIDTH`: **4096**: Maximum avatar image width in pixels. - `AVATAR_MAX_HEIGHT`: **3072**: Maximum avatar image height in pixels. - `AVATAR_MAX_FILE_SIZE`: **1048576** (1Mb): Maximum avatar image file size in bytes. +- `AVATAR_RENDERED_SIZE_FACTOR`: **3**: The multiplication factor for rendered avatar images. Larger values result in finer rendering on HiDPI devices. - `REPOSITORY_AVATAR_STORAGE_TYPE`: **default**: Storage type defined in `[storage.xxx]`. Default is `default` which will read `[storage]` if no section `[storage]` will be a type `local`. - `REPOSITORY_AVATAR_UPLOAD_PATH`: **data/repo-avatars**: Path to store repository avatar image files. diff --git a/models/avatars/avatar.go b/models/avatars/avatar.go index da63dfd10..7206a8ae9 100644 --- a/models/avatars/avatar.go +++ b/models/avatars/avatar.go @@ -21,9 +21,6 @@ import ( // DefaultAvatarPixelSize is the default size in pixels of a rendered avatar const DefaultAvatarPixelSize = 28 -// AvatarRenderedSizeFactor is the factor by which the default size is increased for finer rendering -const AvatarRenderedSizeFactor = 4 - // EmailHash represents a pre-generated hash map (mainly used by LibravatarURL, it queries email server's DNS records) type EmailHash struct { Hash string `xorm:"pk varchar(32)"` diff --git a/modules/repository/commits.go b/modules/repository/commits.go index 8e727c95d..9ff9a9531 100644 --- a/modules/repository/commits.go +++ b/modules/repository/commits.go @@ -13,6 +13,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" api "code.gitea.io/gitea/modules/structs" ) @@ -141,7 +142,7 @@ func (pc *PushCommits) AvatarLink(email string) string { return avatar } - size := avatars.DefaultAvatarPixelSize * avatars.AvatarRenderedSizeFactor + size := avatars.DefaultAvatarPixelSize * setting.Avatar.RenderedSizeFactor u, ok := pc.emailUsers[email] if !ok { diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index 30edf3362..d01388fe1 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -124,13 +124,13 @@ func TestPushCommits_AvatarLink(t *testing.T) { } assert.Equal(t, - "https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=112", + "https://secure.gravatar.com/avatar/ab53a2911ddf9b4817ac01ddcd3d975f?d=identicon&s=84", pushCommits.AvatarLink("user2@example.com")) assert.Equal(t, "https://secure.gravatar.com/avatar/"+ fmt.Sprintf("%x", md5.Sum([]byte("nonexistent@example.com")))+ - "?d=identicon&s=112", + "?d=identicon&s=84", pushCommits.AvatarLink("nonexistent@example.com")) } diff --git a/modules/setting/picture.go b/modules/setting/picture.go index 415552d7c..a6d3447dc 100644 --- a/modules/setting/picture.go +++ b/modules/setting/picture.go @@ -18,13 +18,15 @@ var ( Avatar = struct { Storage - MaxWidth int - MaxHeight int - MaxFileSize int64 + MaxWidth int + MaxHeight int + MaxFileSize int64 + RenderedSizeFactor int }{ - MaxWidth: 4096, - MaxHeight: 3072, - MaxFileSize: 1048576, + MaxWidth: 4096, + MaxHeight: 3072, + MaxFileSize: 1048576, + RenderedSizeFactor: 3, } GravatarSource string @@ -55,6 +57,7 @@ func newPictureService() { Avatar.MaxWidth = sec.Key("AVATAR_MAX_WIDTH").MustInt(4096) Avatar.MaxHeight = sec.Key("AVATAR_MAX_HEIGHT").MustInt(3072) Avatar.MaxFileSize = sec.Key("AVATAR_MAX_FILE_SIZE").MustInt64(1048576) + Avatar.RenderedSizeFactor = sec.Key("AVATAR_RENDERED_SIZE_FACTOR").MustInt(3) switch source := sec.Key("GRAVATAR_SOURCE").MustString("gravatar"); source { case "duoshuo": diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 1841ad273..c1c6b4034 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -557,17 +557,17 @@ func Avatar(item interface{}, others ...interface{}) template.HTML { switch t := item.(type) { case *user_model.User: - src := t.AvatarLinkWithSize(size * avatars.AvatarRenderedSizeFactor) + src := t.AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor) if src != "" { return AvatarHTML(src, size, class, t.DisplayName()) } case *models.Collaborator: - src := t.AvatarLinkWithSize(size * avatars.AvatarRenderedSizeFactor) + src := t.AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor) if src != "" { return AvatarHTML(src, size, class, t.DisplayName()) } case *models.Organization: - src := t.AsUser().AvatarLinkWithSize(size * avatars.AvatarRenderedSizeFactor) + src := t.AsUser().AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor) if src != "" { return AvatarHTML(src, size, class, t.AsUser().DisplayName()) } @@ -596,7 +596,7 @@ func RepoAvatar(repo *repo_model.Repository, others ...interface{}) template.HTM // AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string) func AvatarByEmail(email string, name string, others ...interface{}) template.HTML { size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar image", others...) - src := avatars.GenerateEmailAvatarFastLink(email, size*avatars.AvatarRenderedSizeFactor) + src := avatars.GenerateEmailAvatarFastLink(email, size*setting.Avatar.RenderedSizeFactor) if src != "" { return AvatarHTML(src, size, class, name)