jojo/modules
Antonin Delpeuch 0a57672544 feat: serve downsized versions of avatars (#11242)
Fixes #2325.

This introduces a way to download downsized versions of the user and repository avatars:
* `/avatars/123abcd` still serves the full-size avatar
* `/avatars/123abcd?size=64` serves it at size 64x64 px

Those downsized versions are computed on demand when requested for the first time and cached. The caching is done in a storage location configurable in the instance settings, just like the storage locations for the full-sized avatars are. The sizes of the downsized images are restricted to a fixed set of sizes, so that the cache doesn't grow too big. The caching and resizing logic is exposed in a way that could potentially be reused for other types of images (such as user uploads in issue discussions).

Luckily, the Go templates already specify in many places which size those avatars should be rendered, even if this information was only used for external avatar providers (such as Gravatar) until now.

The range of sizes requested by the HTML templates is rather wide: the table below lists all the sizes I could find, and the corresponding size served by the backend with the logic I implemented. The scaling factor of 2 was already used for requesting resized external avatars, and likely exists to make sure that users with display scaling enabled get a sharper picture.

| Size requested in the template | After scaling (x2)  | Size of the image served |
|---------|---------|---------|
| 256 px |  512 px | original (512 px) |
| 140 px | 280 px | original (512 px) |
| 48 px | 96 px | 128 px |
| 40 px | 80 px | 128 px |
| 32 px | 64 px | 64 px |
| 28 px | 56 px | 64 px |
| 24 px | 48 px | 64 px |
| 20 px | 40 px | 64 px |

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/11242
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
2026-05-16 12:04:05 +02:00
..
actions feat: reusable workflow outer job is skipped if 'if:' block skips workflow (#12412) 2026-05-05 02:59:34 +02:00
activitypub feat: backend DB model for fine-grained repo access tokens 2026-02-27 17:17:29 +01:00
analyze Rename code_langauge.go to code_language.go (#26377) 2023-08-07 15:00:53 -04:00
assetfs feat: optimization: use fs.ReadFile (#10987) 2026-01-22 16:26:18 +01:00
auth chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
avatar feat: serve downsized versions of avatars (#11242) 2026-05-16 12:04:05 +02:00
avatarstore feat: serve downsized versions of avatars (#11242) 2026-05-16 12:04:05 +02:00
base fix: "Follow symlink" to work with arbitrary links (#12246) 2026-04-27 23:54:21 +02:00
cache feat: cache OIDC metadata & JWKS when read by authorized integration (#12275) 2026-04-28 02:13:06 +02:00
card chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
charset chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
container chore: add new functions to container.Set 2025-10-14 14:40:49 -06:00
csv Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
emoji chore(cleanup): replaces unnecessary calls to formatting functions by non-formatting equivalents (#7994) 2025-05-29 17:34:29 +02:00
eventsource ci: detect and prevent empty case statements in Go code (#11593) 2026-03-10 02:50:28 +01:00
forgefed chore(federation): re-enable nilnil lint (#11253) 2026-04-13 22:05:29 +02:00
generate chore: unify signing key configuration across modules (#11194) 2026-04-21 19:39:33 +02:00
git fix: return the error when InitDelegateHooks fail (#12427) 2026-05-06 04:47:15 +02:00
gitrepo Update module github.com/golangci/golangci-lint/v2/cmd/golangci-lint to v2.6.1 (forgejo) (#10053) 2025-11-11 07:04:35 +01:00
graceful ci: detect and prevent empty case statements in Go code (#11593) 2026-03-10 02:50:28 +01:00
hcaptcha chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
highlight fix(ui): show "Shell" instead of "Bash" in headers of shell script files (#12562) 2026-05-14 22:33:51 +02:00
hostmatcher chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
html Refactor backend SVG package and add tests (#26335) 2023-08-05 04:34:59 +00:00
httpcache chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
httplib chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
indexer fix(issue-search): single exclude query was erroneosly considered as must (#12589) 2026-05-16 09:57:51 +02:00
issue/template chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
json Replace interface{} with any (#25686) 2023-07-04 18:36:08 +00:00
jwtx chore: make use of go1.26 features (#12369) 2026-05-01 22:51:48 +02:00
keying fix: store pull mirror creds encrypted with keying (#11909) 2026-04-04 13:53:22 +02:00
label chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
lfs chore: add unit test for SearchPointerBlobs 2025-10-03 14:37:24 +02:00
log tests: make buffer log writer thread safe (#11962) 2026-04-04 16:29:14 +02:00
markup feat(ui): support Pandoc style code blocks (#12099) 2026-05-12 00:53:09 +02:00
mcaptcha chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
metrics chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
migration ci: detect and prevent empty case statements in Go code (#11593) 2026-03-10 02:50:28 +01:00
nosql feat: cache OIDC metadata & JWKS when read by authorized integration (#12275) 2026-04-28 02:13:06 +02:00
optional chore: support Option[T] as a type on database schema structs (#11553) 2026-03-08 03:36:32 +01:00
options chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
packages feat: support simple JSON API for PyPI package registry (#12095) 2026-04-30 16:58:28 +02:00
paginator Use more specific test methods (#24265) 2023-04-22 17:56:27 -04:00
pprof chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
private chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
process Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
proxy chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
proxyprotocol ci: detect and prevent empty case statements in Go code (#11593) 2026-03-10 02:50:28 +01:00
public chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
queue feat: cache OIDC metadata & JWKS when read by authorized integration (#12275) 2026-04-28 02:13:06 +02:00
recaptcha chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
references fix: pull request cross references (#7979) 2025-05-28 14:50:05 +02:00
regexplru Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
repository feat: serve downsized versions of avatars (#11242) 2026-05-16 12:04:05 +02:00
secret Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v1.64.6 (forgejo) (#7118) 2025-03-04 21:38:35 +00:00
session fix: only destroy session if exists 2026-03-19 02:18:52 +01:00
setting chore: remove #11024 workarounds (#12301) 2026-05-01 22:10:10 +02:00
sitemap Add testifylint to lint checks (#4535) 2024-07-30 19:41:10 +00:00
ssh fix: don't clobber authorized_keys file during installation (#10948) 2026-01-23 18:38:09 +01:00
storage chore: unify signing key configuration across modules (#11194) 2026-04-21 19:39:33 +02:00
structs feat: expose run_id in ...actions/runners/jobs endpoint (#12480) 2026-05-09 02:31:03 +02:00
svg chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
sync chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
system Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
templates feat: Follow remote users; feed tab (#10380) 2026-04-12 03:31:03 +02:00
test feat: Follow remote users; feed tab (#10380) 2026-04-12 03:31:03 +02:00
testimport chore: move all test blank imports in a single package (#10662) 2026-01-02 05:32:32 +01:00
testlogger chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
timeutil Update module github.com/golangci/golangci-lint/cmd/golangci-lint to v2 (forgejo) (#7367) 2025-03-28 22:22:21 +00:00
translation fix(i18n): don't log harmless missing translations as errors (#12183) 2026-04-18 23:18:02 +02:00
turnstile chore: branding import path (#7337) 2025-03-27 19:40:14 +00:00
typesniffer feat: detect Interlisp sources as text (#8377) 2025-07-02 07:38:46 +02:00
updatechecker chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
uri Add testifylint to lint checks (#4535) 2024-07-30 19:41:10 +00:00
user Drop SSPI auth support and more Windows files (#7148) 2025-03-08 00:43:41 +00:00
util chore: make use of go1.26 features (#12369) 2026-05-01 22:51:48 +02:00
validation chore: update github.com/go-ap/activitypub to 902f6cf (#11301) 2026-04-02 23:57:13 +02:00
web chore: add modernizer linter (#11936) 2026-04-02 03:29:37 +02:00
webhook Actions Failure, Succes, Recover Webhooks (#7508) 2025-06-03 14:29:19 +02:00
zstd Cache generated binary across jobs 2024-08-26 23:43:09 +02:00