diff --git a/routers/web/repo/issue_test.go b/routers/web/repo/issue_test.go index bdfce6af5c9..9db2a73ca78 100644 --- a/routers/web/repo/issue_test.go +++ b/routers/web/repo/issue_test.go @@ -7,10 +7,34 @@ import ( "testing" issues_model "gitea.dev/models/issues" + "gitea.dev/modules/references" "github.com/stretchr/testify/assert" ) +func TestCombineXRefComments(t *testing.T) { + none, closes, neutered := references.XRefActionNone, references.XRefActionCloses, references.XRefActionNeutered + xref := func(id, refIssueID, refCommentID int64, action references.XRefAction) *issues_model.Comment { + return &issues_model.Comment{ID: id, Type: issues_model.CommentTypeIssueRef, RefIssueID: refIssueID, RefCommentID: refCommentID, RefAction: action} + } + issue := issues_model.Issue{Comments: issues_model.CommentList{ + xref(1, 10, 1, neutered), + xref(2, 11, 2, none), + xref(3, 10, 3, none), + xref(4, 11, 4, closes), + xref(5, 11, 5, neutered), + xref(6, 0, 0, none), + xref(7, 0, 0, none), + }} + combineXRefComments(&issue) + assert.Equal(t, issues_model.CommentList{ + xref(1, 10, 3, none), + xref(2, 11, 2, closes), + xref(6, 0, 0, none), + xref(7, 0, 0, none), + }, issue.Comments) +} + func TestCombineLabelComments(t *testing.T) { kases := []struct { name string diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go index 7e948e8930a..06d55f938e2 100644 --- a/routers/web/repo/issue_view.go +++ b/routers/web/repo/issue_view.go @@ -27,6 +27,7 @@ import ( "gitea.dev/modules/log" "gitea.dev/modules/markup" "gitea.dev/modules/markup/markdown" + "gitea.dev/modules/references" "gitea.dev/modules/setting" "gitea.dev/modules/svg" "gitea.dev/modules/templates/vars" @@ -189,6 +190,32 @@ func filterXRefComments(ctx *context.Context, issue *issues_model.Issue) error { return nil } +// combineXRefComments keeps only the first reference from each issue, carrying over the action of later ones +func combineXRefComments(issue *issues_model.Issue) { + first := make(map[int64]*issues_model.Comment) + for i := 0; i < len(issue.Comments); { + c := issue.Comments[i] + if !issues_model.CommentTypeIsRef(c.Type) || c.RefIssueID == 0 { + i++ + continue + } + prev, ok := first[c.RefIssueID] + if !ok { + first[c.RefIssueID] = c + i++ + continue + } + switch { + case c.RefAction == references.XRefActionNeutered: // a removed mention never overrides a live one + case prev.RefAction == references.XRefActionNeutered: + prev.RefAction, prev.RefCommentID = c.RefAction, c.RefCommentID + case c.RefAction != references.XRefActionNone: + prev.RefAction = c.RefAction + } + issue.Comments = append(issue.Comments[:i], issue.Comments[i+1:]...) + } +} + // combineLabelComments combine the nearby label comments as one. func combineLabelComments(issue *issues_model.Issue) { var prev, cur *issues_model.Comment @@ -346,6 +373,7 @@ func ViewIssue(ctx *context.Context) { ctx.ServerError("filterXRefComments", err) return } + combineXRefComments(issue) ctx.Data["Title"] = fmt.Sprintf("#%d - %s", issue.Index, emoji.ReplaceAliases(issue.Title))