diff --git a/models/issue_comment.go b/models/issue_comment.go index 5c053ec02a..63256ddc99 100644 --- a/models/issue_comment.go +++ b/models/issue_comment.go @@ -124,7 +124,9 @@ type Comment struct { IssueID int64 `xorm:"INDEX"` Issue *Issue `xorm:"-"` LabelID int64 - Label *Label `xorm:"-"` + Label *Label `xorm:"-"` + AddedLabels []*Label `xorm:"-"` + RemovedLabels []*Label `xorm:"-"` OldProjectID int64 ProjectID int64 OldProject *Project `xorm:"-"` diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 63be27d987..03ec80f99c 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -343,6 +343,16 @@ func NewFuncMap() []template.FuncMap { // the table is NOT sorted with this header return "" }, + "RenderLabels": func(labels []*models.Label) template.HTML { + html := "" + + for _, label := range labels { + html = fmt.Sprintf("%s
%s
", + html, label.ForegroundColor(), label.Color, RenderEmoji(label.Name)) + } + + return template.HTML(html) + }, }} } diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 9864346bac..60557aea76 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -979,8 +979,11 @@ issues.label_templates.info = No labels exist yet. Create a label with 'New Labe issues.label_templates.helper = Select a label set issues.label_templates.use = Use Label Set issues.label_templates.fail_to_load_file = Failed to load label template file '%s': %v -issues.add_label_at = added the
%s
label %s -issues.remove_label_at = removed the
%s
label %s +issues.add_label = added the %s label %s +issues.add_labels = added the %s labels %s +issues.remove_label = removed the %s label %s +issues.remove_labels = removed the %s labels %s +issues.add_remove_labels = added %s and removed %s labels %s issues.add_milestone_at = `added this to the %s milestone %s` issues.add_project_at = `added this to the %s project %s` issues.change_milestone_at = `modified the milestone from %s to %s %s` diff --git a/routers/repo/issue.go b/routers/repo/issue.go index 835a952e5e..1763b1c1a2 100644 --- a/routers/repo/issue.go +++ b/routers/repo/issue.go @@ -1354,6 +1354,9 @@ func ViewIssue(ctx *context.Context) { } } + // Combine multiple label assignments into a single comment + combineLabelComments(issue) + getBranchData(ctx, issue) if issue.IsPull { pull := issue.PullRequest @@ -2385,3 +2388,46 @@ func attachmentsHTML(ctx *context.Context, attachments []*models.Attachment) str } return attachHTML } + +func combineLabelComments(issue *models.Issue) { + for i := 0; i < len(issue.Comments); { + c := issue.Comments[i] + var shouldMerge bool + var removingCur bool + var prev *models.Comment + + if i == 0 { + shouldMerge = false + } else { + prev = issue.Comments[i-1] + removingCur = c.Content != "1" + + shouldMerge = prev.PosterID == c.PosterID && c.CreatedUnix-prev.CreatedUnix < 60 && + c.Type == prev.Type + } + + if c.Type == models.CommentTypeLabel { + if !shouldMerge { + if removingCur { + c.RemovedLabels = make([]*models.Label, 1) + c.AddedLabels = make([]*models.Label, 0) + c.RemovedLabels[0] = c.Label + } else { + c.RemovedLabels = make([]*models.Label, 0) + c.AddedLabels = make([]*models.Label, 1) + c.AddedLabels[0] = c.Label + } + } else { + if removingCur { + prev.RemovedLabels = append(prev.RemovedLabels, c.Label) + } else { + prev.AddedLabels = append(prev.AddedLabels, c.Label) + } + prev.CreatedUnix = c.CreatedUnix + issue.Comments = append(issue.Comments[:i], issue.Comments[i+1:]...) + continue + } + } + i++ + } +} diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 68bb2d49f7..e37c7e7fdd 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -161,7 +161,7 @@ {{else if eq .Type 7}} - {{if .Label}} + {{if or .AddedLabels .RemovedLabels}}
{{svg "octicon-tag"}} @@ -169,7 +169,13 @@ {{.Poster.GetDisplayName}} - {{if .Content}}{{$.i18n.Tr "repo.issues.add_label_at" .Label.ForegroundColor .Label.Color (.Label.Name|RenderEmoji) $createdStr | Safe}}{{else}}{{$.i18n.Tr "repo.issues.remove_label_at" .Label.ForegroundColor .Label.Color (.Label.Name|RenderEmoji) $createdStr | Safe}}{{end}} + {{if and .AddedLabels (not .RemovedLabels)}} + {{$.i18n.Tr (TrN $.i18n.Lang (len .AddedLabels) "repo.issues.add_label" "repo.issues.add_labels") (RenderLabels .AddedLabels) $createdStr | Safe}} + {{else if and (not .AddedLabels) .RemovedLabels}} + {{$.i18n.Tr (TrN $.i18n.Lang (len .RemovedLabels) "repo.issues.remove_label" "repo.issues.remove_labels") (RenderLabels .RemovedLabels) $createdStr | Safe}} + {{else}} + {{$.i18n.Tr "repo.issues.add_remove_labels" (RenderLabels .AddedLabels) (RenderLabels .RemovedLabels) $createdStr | Safe}} + {{end}}
{{end}}