feat: add activity heatmap on profile overview
Some checks failed
Build and Release / Create Release (push) Has been skipped
Build and Release / Integration Tests (PostgreSQL) (push) Successful in 1m36s
Build and Release / Lint (push) Failing after 1m55s
Build and Release / Build Binaries (amd64, darwin) (push) Has been skipped
Build and Release / Build Binaries (amd64, linux) (push) Has been skipped
Build and Release / Build Binaries (amd64, windows) (push) Has been skipped
Build and Release / Build Binaries (arm64, darwin) (push) Has been skipped
Build and Release / Build Binaries (arm64, linux) (push) Has been skipped
Build and Release / Unit Tests (push) Successful in 2m4s

- Add ShowHeatmapOnProfile field to user model
- Add checkbox in user settings under privacy section
- Display heatmap on profile overview page when enabled
- Users can now show their contribution activity on their profile

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
David H Friedel Jr 2026-01-11 02:22:40 +00:00
parent 1986d90df0
commit 54510ce582
8 changed files with 3857 additions and 3817 deletions

View File

@ -149,7 +149,8 @@ type User struct {
// Preferences
DiffViewStyle string `xorm:"NOT NULL DEFAULT ''"`
Theme string `xorm:"NOT NULL DEFAULT ''"`
KeepActivityPrivate bool `xorm:"NOT NULL DEFAULT false"`
KeepActivityPrivate bool `xorm:"NOT NULL DEFAULT false"`
ShowHeatmapOnProfile bool `xorm:"NOT NULL DEFAULT false"`
}
// Meta defines the meta information of a user, to be stored in the K/V table

File diff suppressed because it is too large Load Diff

View File

@ -247,6 +247,17 @@ func prepareUserProfileTabData(ctx *context.Context, profileDbRepo *repo_model.R
total = int(count)
case "overview":
// Load heatmap if user has it enabled
if ctx.ContextUser.ShowHeatmapOnProfile && setting.Service.EnableUserHeatmap {
data, err := activities_model.GetUserHeatmapDataByUser(ctx, ctx.ContextUser, ctx.Doer)
if err != nil {
log.Error("GetUserHeatmapDataByUser: %v", err)
} else {
ctx.Data["HeatmapData"] = data
ctx.Data["HeatmapTotalContributions"] = activities_model.GetTotalContributionsInHeatmap(data)
}
}
// Load pinned repositories
pinnedRepos, err := user_model.GetUserPinnedRepos(ctx, ctx.ContextUser.ID)
if err != nil {

View File

@ -102,7 +102,8 @@ func ProfilePost(ctx *context.Context) {
Website: optional.Some(form.Website),
Location: optional.Some(form.Location),
Visibility: optional.Some(form.Visibility),
KeepActivityPrivate: optional.Some(form.KeepActivityPrivate),
KeepActivityPrivate: optional.Some(form.KeepActivityPrivate),
ShowHeatmapOnProfile: optional.Some(form.ShowHeatmapOnProfile),
}
if form.FullName != "" {

View File

@ -218,7 +218,8 @@ type UpdateProfileForm struct {
Location string `binding:"MaxSize(50)"`
Description string `binding:"MaxSize(255)"`
Visibility structs.VisibleType
KeepActivityPrivate bool
KeepActivityPrivate bool
ShowHeatmapOnProfile bool
}
// Validate validates the fields

View File

@ -47,6 +47,7 @@ type UpdateOptions struct {
IsRestricted optional.Option[bool]
Visibility optional.Option[structs.VisibleType]
KeepActivityPrivate optional.Option[bool]
ShowHeatmapOnProfile optional.Option[bool]
Language optional.Option[string]
Theme optional.Option[string]
DiffViewStyle optional.Option[string]
@ -158,6 +159,11 @@ func UpdateUser(ctx context.Context, u *user_model.User, opts *UpdateOptions) er
cols = append(cols, "keep_activity_private")
}
if opts.ShowHeatmapOnProfile.Has() {
u.ShowHeatmapOnProfile = opts.ShowHeatmapOnProfile.Value()
cols = append(cols, "show_heatmap_on_profile")
}
if opts.AllowCreateOrganization.Has() {
u.AllowCreateOrganization = opts.AllowCreateOrganization.Value()

View File

@ -26,6 +26,16 @@
{{else if eq .TabName "followers"}}
{{template "repo/user_cards" .}}
{{else if eq .TabName "overview"}}
{{/* Activity Heatmap on Overview */}}
{{if and .ContextUser.ShowHeatmapOnProfile .HeatmapData}}
<div class="ui segment tw-mb-4">
<h4 class="ui header tw-flex tw-items-center">
{{svg "octicon-graph" 16}} {{ctx.Locale.Tr "user.activity_heatmap"}}
</h4>
{{template "user/heatmap" .}}
</div>
{{end}}
{{/* Pinned Repositories Section */}}
{{if or .UserPinnedRepos .IsContextUserProfile}}
<div class="ui segment pinned-repos-section tw-mb-4">

View File

@ -88,6 +88,13 @@
</div>
</div>
<div class="field">
<div class="ui checkbox" id="show-heatmap-on-profile">
<label data-tooltip-content="{{ctx.Locale.Tr "settings.show_heatmap_on_profile_popup"}}"><strong>{{ctx.Locale.Tr "settings.show_heatmap_on_profile"}}</strong></label>
<input name="show_heatmap_on_profile" type="checkbox" {{if .SignedUser.ShowHeatmapOnProfile}}checked{{end}}>
</div>
</div>
<div class="divider"></div>
<div class="field">