Skip to content

Commit

Permalink
Make AvatarRenderedSizeFactor configurable and set it to 3 (#17951)
Browse files Browse the repository at this point in the history
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: #17422
Fixes: #16287

Co-authored-by: wxiaoguang <[email protected]>
  • Loading branch information
silverwind and wxiaoguang authored Dec 16, 2021
1 parent e78ee73 commit cc129d2
Show file tree
Hide file tree
Showing 7 changed files with 22 additions and 16 deletions.
4 changes: 4 additions & 0 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
3 changes: 0 additions & 3 deletions models/avatars/avatar.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)"`
Expand Down
3 changes: 2 additions & 1 deletion modules/repository/commits.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)

Expand Down Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions modules/repository/commits_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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("[email protected]"))

assert.Equal(t,
"https://secure.gravatar.com/avatar/"+
fmt.Sprintf("%x", md5.Sum([]byte("[email protected]")))+
"?d=identicon&s=112",
"?d=identicon&s=84",
pushCommits.AvatarLink("[email protected]"))
}

Expand Down
15 changes: 9 additions & 6 deletions modules/setting/picture.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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":
Expand Down
8 changes: 4 additions & 4 deletions modules/templates/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -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())
}
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit cc129d2

Please sign in to comment.