mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-06-01 04:12:10 +00:00
feat: combine review requests comments
- Combine review requests comments similairy how labels comments are combined. If review requests comments were made within 60 seconds of each other they will be grouped. - Integration and unit test added. - Resolves #2774
This commit is contained in:
parent
aa86e94853
commit
8fdc0a7a6c
9 changed files with 685 additions and 65 deletions
|
@ -1825,6 +1825,7 @@ func ViewIssue(ctx *context.Context) {
|
|||
|
||||
// Combine multiple label assignments into a single comment
|
||||
combineLabelComments(issue)
|
||||
combineRequestReviewComments(issue)
|
||||
|
||||
getBranchData(ctx, issue)
|
||||
if issue.IsPull {
|
||||
|
@ -3665,6 +3666,127 @@ func attachmentsHTML(ctx *context.Context, attachments []*repo_model.Attachment,
|
|||
return attachHTML
|
||||
}
|
||||
|
||||
type RequestReviewTarget struct {
|
||||
user *user_model.User
|
||||
team *organization.Team
|
||||
}
|
||||
|
||||
func (t *RequestReviewTarget) ID() int64 {
|
||||
if t.user != nil {
|
||||
return t.user.ID
|
||||
}
|
||||
return t.team.ID
|
||||
}
|
||||
|
||||
func (t *RequestReviewTarget) Name() string {
|
||||
if t.user != nil {
|
||||
return t.user.GetDisplayName()
|
||||
}
|
||||
return t.team.Name
|
||||
}
|
||||
|
||||
func (t *RequestReviewTarget) Type() string {
|
||||
if t.user != nil {
|
||||
return "user"
|
||||
}
|
||||
return "team"
|
||||
}
|
||||
|
||||
// combineRequestReviewComments combine the nearby request review comments as one.
|
||||
func combineRequestReviewComments(issue *issues_model.Issue) {
|
||||
var prev, cur *issues_model.Comment
|
||||
for i := 0; i < len(issue.Comments); i++ {
|
||||
cur = issue.Comments[i]
|
||||
if i > 0 {
|
||||
prev = issue.Comments[i-1]
|
||||
}
|
||||
if i == 0 || cur.Type != issues_model.CommentTypeReviewRequest ||
|
||||
(prev != nil && prev.PosterID != cur.PosterID) ||
|
||||
(prev != nil && cur.CreatedUnix-prev.CreatedUnix >= 60) {
|
||||
if cur.Type == issues_model.CommentTypeReviewRequest && (cur.Assignee != nil || cur.AssigneeTeam != nil) {
|
||||
if cur.RemovedAssignee {
|
||||
if cur.AssigneeTeam != nil {
|
||||
cur.RemovedRequestReview = append(cur.RemovedRequestReview, &RequestReviewTarget{team: cur.AssigneeTeam})
|
||||
} else {
|
||||
cur.RemovedRequestReview = append(cur.RemovedRequestReview, &RequestReviewTarget{user: cur.Assignee})
|
||||
}
|
||||
} else {
|
||||
if cur.AssigneeTeam != nil {
|
||||
cur.AddedRequestReview = append(cur.AddedRequestReview, &RequestReviewTarget{team: cur.AssigneeTeam})
|
||||
} else {
|
||||
cur.AddedRequestReview = append(cur.AddedRequestReview, &RequestReviewTarget{user: cur.Assignee})
|
||||
}
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Previous comment is not a review request, so cannot group. Start a new group.
|
||||
if prev.Type != issues_model.CommentTypeReviewRequest {
|
||||
if cur.RemovedAssignee {
|
||||
if cur.AssigneeTeam != nil {
|
||||
cur.RemovedRequestReview = append(cur.RemovedRequestReview, &RequestReviewTarget{team: cur.AssigneeTeam})
|
||||
} else {
|
||||
cur.RemovedRequestReview = append(cur.RemovedRequestReview, &RequestReviewTarget{user: cur.Assignee})
|
||||
}
|
||||
} else {
|
||||
if cur.AssigneeTeam != nil {
|
||||
cur.AddedRequestReview = append(cur.AddedRequestReview, &RequestReviewTarget{team: cur.AssigneeTeam})
|
||||
} else {
|
||||
cur.AddedRequestReview = append(cur.AddedRequestReview, &RequestReviewTarget{user: cur.Assignee})
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Start grouping.
|
||||
if cur.RemovedAssignee {
|
||||
addedIndex := slices.IndexFunc(prev.AddedRequestReview, func(t issues_model.RequestReviewTarget) bool {
|
||||
if cur.AssigneeTeam != nil {
|
||||
return cur.AssigneeTeam.ID == t.ID() && t.Type() == "team"
|
||||
}
|
||||
return cur.Assignee.ID == t.ID() && t.Type() == "user"
|
||||
})
|
||||
|
||||
// If for this target a AddedRequestReview, then we remove that entry. If it's not found, then add it to the RemovedRequestReview.
|
||||
if addedIndex == -1 {
|
||||
if cur.AssigneeTeam != nil {
|
||||
prev.RemovedRequestReview = append(prev.RemovedRequestReview, &RequestReviewTarget{team: cur.AssigneeTeam})
|
||||
} else {
|
||||
prev.RemovedRequestReview = append(prev.RemovedRequestReview, &RequestReviewTarget{user: cur.Assignee})
|
||||
}
|
||||
} else {
|
||||
prev.AddedRequestReview = slices.Delete(prev.AddedRequestReview, addedIndex, addedIndex+1)
|
||||
}
|
||||
} else {
|
||||
removedIndex := slices.IndexFunc(prev.RemovedRequestReview, func(t issues_model.RequestReviewTarget) bool {
|
||||
if cur.AssigneeTeam != nil {
|
||||
return cur.AssigneeTeam.ID == t.ID() && t.Type() == "team"
|
||||
}
|
||||
return cur.Assignee.ID == t.ID() && t.Type() == "user"
|
||||
})
|
||||
|
||||
// If for this target a RemovedRequestReview, then we remove that entry. If it's not found, then add it to the AddedRequestReview.
|
||||
if removedIndex == -1 {
|
||||
if cur.AssigneeTeam != nil {
|
||||
prev.AddedRequestReview = append(prev.AddedRequestReview, &RequestReviewTarget{team: cur.AssigneeTeam})
|
||||
} else {
|
||||
prev.AddedRequestReview = append(prev.AddedRequestReview, &RequestReviewTarget{user: cur.Assignee})
|
||||
}
|
||||
} else {
|
||||
prev.RemovedRequestReview = slices.Delete(prev.RemovedRequestReview, removedIndex, removedIndex+1)
|
||||
}
|
||||
}
|
||||
|
||||
// Propoagate creation time.
|
||||
prev.CreatedUnix = cur.CreatedUnix
|
||||
|
||||
// Remove the current comment since it has been combined to prev comment
|
||||
issue.Comments = append(issue.Comments[:i], issue.Comments[i+1:]...)
|
||||
i--
|
||||
}
|
||||
}
|
||||
|
||||
// combineLabelComments combine the nearby label comments as one.
|
||||
func combineLabelComments(issue *issues_model.Issue) {
|
||||
var prev, cur *issues_model.Comment
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue