diff --git a/models/activities/notification.go b/models/activities/notification.go index 42af9502ccf..4abacf47793 100644 --- a/models/activities/notification.go +++ b/models/activities/notification.go @@ -13,6 +13,7 @@ import ( issues_model "code.gitea.io/gitea/models/issues" repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/timeutil" @@ -70,6 +71,7 @@ type Notification struct { Comment *issues_model.Comment `xorm:"-"` User *user_model.User `xorm:"-"` Release *repo_model.Release `xorm:"-"` + Commit *git.Commit `xorm:"-"` CreatedUnix timeutil.TimeStamp `xorm:"created NOT NULL"` UpdatedUnix timeutil.TimeStamp `xorm:"updated NOT NULL"` diff --git a/models/activities/notification_list.go b/models/activities/notification_list.go index 732a76feca8..6f3c3812205 100644 --- a/models/activities/notification_list.go +++ b/models/activities/notification_list.go @@ -13,6 +13,8 @@ import ( "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/container" + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/util" @@ -457,12 +459,25 @@ func (nl NotificationList) LoadComments(ctx context.Context) ([]int, error) { return failures, nil } +func (nl NotificationList) getPendingReleaseIDs() []int64 { + ids := make(container.Set[int64], len(nl)) + for _, notification := range nl { + if notification.Release != nil { + continue + } + if notification.ReleaseID > 0 { + ids.Add(notification.ReleaseID) + } + } + return ids.Values() +} + func (nl NotificationList) LoadReleases(ctx context.Context) ([]int, error) { if len(nl) == 0 { return []int{}, nil } - releaseIDs := nl.getPendingCommentIDs() + releaseIDs := nl.getPendingReleaseIDs() releases := make(map[int64]*repo_model.Release, len(releaseIDs)) if err := db.GetEngine(ctx).In("id", releaseIDs).Find(&releases); err != nil { return nil, err @@ -482,6 +497,50 @@ func (nl NotificationList) LoadReleases(ctx context.Context) ([]int, error) { return failures, nil } +func (nl NotificationList) LoadCommits(ctx context.Context) ([]int, error) { + if len(nl) == 0 { + return []int{}, nil + } + + _, _, err := nl.LoadRepos(ctx) + if err != nil { + return nil, err + } + + failures := []int{} + repos := make(map[int64]*git.Repository, len(nl)) + for i, n := range nl { + if n.Source != NotificationSourceCommit || n.CommitID == "" { + continue + } + + repo, ok := repos[n.RepoID] + if !ok { + repo, err = gitrepo.OpenRepository(ctx, n.Repository) + if err != nil { + log.Error("Notification[%d]: Failed to get repo for commit %s: %v", n.ID, n.CommitID, err) + failures = append(failures, i) + continue + } + repos[n.RepoID] = repo + } + n.Commit, err = repo.GetCommit(n.CommitID) + if err != nil { + log.Error("Notification[%d]: Failed to get repo for commit %s: %v", n.ID, n.CommitID, err) + failures = append(failures, i) + continue + } + } + + for _, repo := range repos { + if err := repo.Close(); err != nil { + log.Error("Failed to close repository: %v", err) + } + } + + return failures, nil +} + // LoadIssuePullRequests loads all issues' pull requests if possible func (nl NotificationList) LoadIssuePullRequests(ctx context.Context) error { issues := make(map[int64]*issues_model.Issue, len(nl)) diff --git a/routers/web/user/notification.go b/routers/web/user/notification.go index 610a9b80760..4895df93fa0 100644 --- a/routers/web/user/notification.go +++ b/routers/web/user/notification.go @@ -137,6 +137,22 @@ func getNotifications(ctx *context.Context) { notifications = notifications.Without(failures) failCount += len(failures) + failures, err = notifications.LoadCommits(ctx) + if err != nil { + ctx.ServerError("LoadCommits", err) + return + } + notifications = notifications.Without(failures) + failCount += len(failures) + + failures, err = notifications.LoadReleases(ctx) + if err != nil { + ctx.ServerError("LoadReleases", err) + return + } + notifications = notifications.Without(failures) + failCount += len(failures) + if failCount > 0 { ctx.Flash.Error(fmt.Sprintf("ERROR: %d notifications were removed due to missing parts - check the logs", failCount)) } diff --git a/templates/user/notification/notification_div.tmpl b/templates/user/notification/notification_div.tmpl index 9af2cd53b39..342f432ae0f 100644 --- a/templates/user/notification/notification_div.tmpl +++ b/templates/user/notification/notification_div.tmpl @@ -39,6 +39,10 @@