fix #22691 backport #20821 Co-authored-by: zeripath <art27@cantab.net>tokarchuk/v1.18
parent
2e1afd54b2
commit
1d191f9b5a
@ -0,0 +1,129 @@ |
||||
// Copyright 2022 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package issues |
||||
|
||||
import ( |
||||
"context" |
||||
|
||||
"code.gitea.io/gitea/models/db" |
||||
user_model "code.gitea.io/gitea/models/user" |
||||
"code.gitea.io/gitea/modules/markup" |
||||
"code.gitea.io/gitea/modules/markup/markdown" |
||||
|
||||
"xorm.io/builder" |
||||
) |
||||
|
||||
// CodeComments represents comments on code by using this structure: FILENAME -> LINE (+ == proposed; - == previous) -> COMMENTS
|
||||
type CodeComments map[string]map[int64][]*Comment |
||||
|
||||
// FetchCodeComments will return a 2d-map: ["Path"]["Line"] = Comments at line
|
||||
func FetchCodeComments(ctx context.Context, issue *Issue, currentUser *user_model.User) (CodeComments, error) { |
||||
return fetchCodeCommentsByReview(ctx, issue, currentUser, nil) |
||||
} |
||||
|
||||
func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *user_model.User, review *Review) (CodeComments, error) { |
||||
pathToLineToComment := make(CodeComments) |
||||
if review == nil { |
||||
review = &Review{ID: 0} |
||||
} |
||||
opts := FindCommentsOptions{ |
||||
Type: CommentTypeCode, |
||||
IssueID: issue.ID, |
||||
ReviewID: review.ID, |
||||
} |
||||
|
||||
comments, err := findCodeComments(ctx, opts, issue, currentUser, review) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
for _, comment := range comments { |
||||
if pathToLineToComment[comment.TreePath] == nil { |
||||
pathToLineToComment[comment.TreePath] = make(map[int64][]*Comment) |
||||
} |
||||
pathToLineToComment[comment.TreePath][comment.Line] = append(pathToLineToComment[comment.TreePath][comment.Line], comment) |
||||
} |
||||
return pathToLineToComment, nil |
||||
} |
||||
|
||||
func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issue, currentUser *user_model.User, review *Review) ([]*Comment, error) { |
||||
var comments []*Comment |
||||
if review == nil { |
||||
review = &Review{ID: 0} |
||||
} |
||||
conds := opts.ToConds() |
||||
if review.ID == 0 { |
||||
conds = conds.And(builder.Eq{"invalidated": false}) |
||||
} |
||||
e := db.GetEngine(ctx) |
||||
if err := e.Where(conds). |
||||
Asc("comment.created_unix"). |
||||
Asc("comment.id"). |
||||
Find(&comments); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := issue.LoadRepo(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := CommentList(comments).loadPosters(ctx); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
// Find all reviews by ReviewID
|
||||
reviews := make(map[int64]*Review) |
||||
ids := make([]int64, 0, len(comments)) |
||||
for _, comment := range comments { |
||||
if comment.ReviewID != 0 { |
||||
ids = append(ids, comment.ReviewID) |
||||
} |
||||
} |
||||
if err := e.In("id", ids).Find(&reviews); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
n := 0 |
||||
for _, comment := range comments { |
||||
if re, ok := reviews[comment.ReviewID]; ok && re != nil { |
||||
// If the review is pending only the author can see the comments (except if the review is set)
|
||||
if review.ID == 0 && re.Type == ReviewTypePending && |
||||
(currentUser == nil || currentUser.ID != re.ReviewerID) { |
||||
continue |
||||
} |
||||
comment.Review = re |
||||
} |
||||
comments[n] = comment |
||||
n++ |
||||
|
||||
if err := comment.LoadResolveDoer(); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
if err := comment.LoadReactions(issue.Repo); err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
var err error |
||||
if comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{ |
||||
Ctx: ctx, |
||||
URLPrefix: issue.Repo.Link(), |
||||
Metas: issue.Repo.ComposeMetas(), |
||||
}, comment.Content); err != nil { |
||||
return nil, err |
||||
} |
||||
} |
||||
return comments[:n], nil |
||||
} |
||||
|
||||
// FetchCodeCommentsByLine fetches the code comments for a given treePath and line number
|
||||
func FetchCodeCommentsByLine(ctx context.Context, issue *Issue, currentUser *user_model.User, treePath string, line int64) ([]*Comment, error) { |
||||
opts := FindCommentsOptions{ |
||||
Type: CommentTypeCode, |
||||
IssueID: issue.ID, |
||||
TreePath: treePath, |
||||
Line: line, |
||||
} |
||||
return findCodeComments(ctx, opts, issue, currentUser, nil) |
||||
} |
Loading…
Reference in new issue