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 <wxiaoguang@gmail.com>
This commit is contained in:
parent
e78ee73d71
commit
cc129d2ca2
7 changed files with 22 additions and 16 deletions
|
@ -1587,6 +1587,10 @@ PATH =
|
||||||
;AVATAR_MAX_WIDTH = 4096
|
;AVATAR_MAX_WIDTH = 4096
|
||||||
;AVATAR_MAX_HEIGHT = 3072
|
;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.
|
;; Maximum allowed file size for uploaded avatars.
|
||||||
;; This is to limit the amount of RAM used when resizing the image.
|
;; This is to limit the amount of RAM used when resizing the image.
|
||||||
;AVATAR_MAX_FILE_SIZE = 1048576
|
;AVATAR_MAX_FILE_SIZE = 1048576
|
||||||
|
|
|
@ -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_WIDTH`: **4096**: Maximum avatar image width in pixels.
|
||||||
- `AVATAR_MAX_HEIGHT`: **3072**: Maximum avatar image height 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_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_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.
|
- `REPOSITORY_AVATAR_UPLOAD_PATH`: **data/repo-avatars**: Path to store repository avatar image files.
|
||||||
|
|
|
@ -21,9 +21,6 @@ import (
|
||||||
// DefaultAvatarPixelSize is the default size in pixels of a rendered avatar
|
// DefaultAvatarPixelSize is the default size in pixels of a rendered avatar
|
||||||
const DefaultAvatarPixelSize = 28
|
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)
|
// EmailHash represents a pre-generated hash map (mainly used by LibravatarURL, it queries email server's DNS records)
|
||||||
type EmailHash struct {
|
type EmailHash struct {
|
||||||
Hash string `xorm:"pk varchar(32)"`
|
Hash string `xorm:"pk varchar(32)"`
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
user_model "code.gitea.io/gitea/models/user"
|
user_model "code.gitea.io/gitea/models/user"
|
||||||
"code.gitea.io/gitea/modules/git"
|
"code.gitea.io/gitea/modules/git"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ func (pc *PushCommits) AvatarLink(email string) string {
|
||||||
return avatar
|
return avatar
|
||||||
}
|
}
|
||||||
|
|
||||||
size := avatars.DefaultAvatarPixelSize * avatars.AvatarRenderedSizeFactor
|
size := avatars.DefaultAvatarPixelSize * setting.Avatar.RenderedSizeFactor
|
||||||
|
|
||||||
u, ok := pc.emailUsers[email]
|
u, ok := pc.emailUsers[email]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -124,13 +124,13 @@ func TestPushCommits_AvatarLink(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(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"))
|
pushCommits.AvatarLink("user2@example.com"))
|
||||||
|
|
||||||
assert.Equal(t,
|
assert.Equal(t,
|
||||||
"https://secure.gravatar.com/avatar/"+
|
"https://secure.gravatar.com/avatar/"+
|
||||||
fmt.Sprintf("%x", md5.Sum([]byte("nonexistent@example.com")))+
|
fmt.Sprintf("%x", md5.Sum([]byte("nonexistent@example.com")))+
|
||||||
"?d=identicon&s=112",
|
"?d=identicon&s=84",
|
||||||
pushCommits.AvatarLink("nonexistent@example.com"))
|
pushCommits.AvatarLink("nonexistent@example.com"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,12 @@ var (
|
||||||
MaxWidth int
|
MaxWidth int
|
||||||
MaxHeight int
|
MaxHeight int
|
||||||
MaxFileSize int64
|
MaxFileSize int64
|
||||||
|
RenderedSizeFactor int
|
||||||
}{
|
}{
|
||||||
MaxWidth: 4096,
|
MaxWidth: 4096,
|
||||||
MaxHeight: 3072,
|
MaxHeight: 3072,
|
||||||
MaxFileSize: 1048576,
|
MaxFileSize: 1048576,
|
||||||
|
RenderedSizeFactor: 3,
|
||||||
}
|
}
|
||||||
|
|
||||||
GravatarSource string
|
GravatarSource string
|
||||||
|
@ -55,6 +57,7 @@ func newPictureService() {
|
||||||
Avatar.MaxWidth = sec.Key("AVATAR_MAX_WIDTH").MustInt(4096)
|
Avatar.MaxWidth = sec.Key("AVATAR_MAX_WIDTH").MustInt(4096)
|
||||||
Avatar.MaxHeight = sec.Key("AVATAR_MAX_HEIGHT").MustInt(3072)
|
Avatar.MaxHeight = sec.Key("AVATAR_MAX_HEIGHT").MustInt(3072)
|
||||||
Avatar.MaxFileSize = sec.Key("AVATAR_MAX_FILE_SIZE").MustInt64(1048576)
|
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 {
|
switch source := sec.Key("GRAVATAR_SOURCE").MustString("gravatar"); source {
|
||||||
case "duoshuo":
|
case "duoshuo":
|
||||||
|
|
|
@ -557,17 +557,17 @@ func Avatar(item interface{}, others ...interface{}) template.HTML {
|
||||||
|
|
||||||
switch t := item.(type) {
|
switch t := item.(type) {
|
||||||
case *user_model.User:
|
case *user_model.User:
|
||||||
src := t.AvatarLinkWithSize(size * avatars.AvatarRenderedSizeFactor)
|
src := t.AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor)
|
||||||
if src != "" {
|
if src != "" {
|
||||||
return AvatarHTML(src, size, class, t.DisplayName())
|
return AvatarHTML(src, size, class, t.DisplayName())
|
||||||
}
|
}
|
||||||
case *models.Collaborator:
|
case *models.Collaborator:
|
||||||
src := t.AvatarLinkWithSize(size * avatars.AvatarRenderedSizeFactor)
|
src := t.AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor)
|
||||||
if src != "" {
|
if src != "" {
|
||||||
return AvatarHTML(src, size, class, t.DisplayName())
|
return AvatarHTML(src, size, class, t.DisplayName())
|
||||||
}
|
}
|
||||||
case *models.Organization:
|
case *models.Organization:
|
||||||
src := t.AsUser().AvatarLinkWithSize(size * avatars.AvatarRenderedSizeFactor)
|
src := t.AsUser().AvatarLinkWithSize(size * setting.Avatar.RenderedSizeFactor)
|
||||||
if src != "" {
|
if src != "" {
|
||||||
return AvatarHTML(src, size, class, t.AsUser().DisplayName())
|
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)
|
// AvatarByEmail renders avatars by email address. args: email, name, size (int), class (string)
|
||||||
func AvatarByEmail(email string, name string, others ...interface{}) template.HTML {
|
func AvatarByEmail(email string, name string, others ...interface{}) template.HTML {
|
||||||
size, class := parseOthers(avatars.DefaultAvatarPixelSize, "ui avatar image", others...)
|
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 != "" {
|
if src != "" {
|
||||||
return AvatarHTML(src, size, class, name)
|
return AvatarHTML(src, size, class, name)
|
||||||
|
|
Reference in a new issue