[BUG] split code conversations in diff tab (#2306)
Follow-up of #2282 and #2296 (which tried to address #2278) One of the issue with the previous PR is that when a conversation on the Files tab was marked as "resolved", it would fetch all the comments for that line (even the outdated ones, which should not be shown on this page - except when explicitly activated). To properly fix this, I have changed `FetchCodeCommentsByLine` to `FetchCodeConversation`. Its role is to fetch all comments related to a given (review, path, line) and reverted my changes in the template (which were based on a misunderstanding). Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/2306 Reviewed-by: Earl Warren <earl-warren@noreply.codeberg.org> Reviewed-by: Gusted <gusted@noreply.codeberg.org> Co-authored-by: oliverpool <git@olivier.pfad.fr> Co-committed-by: oliverpool <git@olivier.pfad.fr>
This commit is contained in:
parent
1e364cc21f
commit
0fc61c8836
11 changed files with 348 additions and 144 deletions
|
@ -14,15 +14,58 @@ import (
|
|||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// CodeConversation contains the comment of a given review
|
||||
type CodeConversation []*Comment
|
||||
|
||||
// CodeConversationsAtLine contains the conversations for a given line
|
||||
type CodeConversationsAtLine map[int64][]CodeConversation
|
||||
|
||||
// CodeConversationsAtLineAndTreePath contains the conversations for a given TreePath and line
|
||||
type CodeConversationsAtLineAndTreePath map[string]CodeConversationsAtLine
|
||||
|
||||
func newCodeConversationsAtLineAndTreePath(comments []*Comment) CodeConversationsAtLineAndTreePath {
|
||||
tree := make(CodeConversationsAtLineAndTreePath)
|
||||
for _, comment := range comments {
|
||||
tree.insertComment(comment)
|
||||
}
|
||||
return tree
|
||||
}
|
||||
|
||||
func (tree CodeConversationsAtLineAndTreePath) insertComment(comment *Comment) {
|
||||
// attempt to append comment to existing conversations (i.e. list of comments belonging to the same review)
|
||||
for i, conversation := range tree[comment.TreePath][comment.Line] {
|
||||
if conversation[0].ReviewID == comment.ReviewID {
|
||||
tree[comment.TreePath][comment.Line][i] = append(conversation, comment)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// no previous conversation was found at this line, create it
|
||||
if tree[comment.TreePath] == nil {
|
||||
tree[comment.TreePath] = make(map[int64][]CodeConversation)
|
||||
}
|
||||
|
||||
tree[comment.TreePath][comment.Line] = append(tree[comment.TreePath][comment.Line], CodeConversation{comment})
|
||||
}
|
||||
|
||||
// FetchCodeConversations will return a 2d-map: ["Path"]["Line"] = List of CodeConversation (one per review) for this line
|
||||
func FetchCodeConversations(ctx context.Context, issue *Issue, doer *user_model.User, showOutdatedComments bool) (CodeConversationsAtLineAndTreePath, error) {
|
||||
opts := FindCommentsOptions{
|
||||
Type: CommentTypeCode,
|
||||
IssueID: issue.ID,
|
||||
}
|
||||
comments, err := findCodeComments(ctx, opts, issue, doer, nil, showOutdatedComments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return newCodeConversationsAtLineAndTreePath(comments), nil
|
||||
}
|
||||
|
||||
// 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, showOutdatedComments bool) (CodeComments, error) {
|
||||
return fetchCodeCommentsByReview(ctx, issue, currentUser, nil, showOutdatedComments)
|
||||
}
|
||||
|
||||
func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *user_model.User, review *Review, showOutdatedComments bool) (CodeComments, error) {
|
||||
func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, doer *user_model.User, review *Review, showOutdatedComments bool) (CodeComments, error) {
|
||||
pathToLineToComment := make(CodeComments)
|
||||
if review == nil {
|
||||
review = &Review{ID: 0}
|
||||
|
@ -33,7 +76,7 @@ func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *u
|
|||
ReviewID: review.ID,
|
||||
}
|
||||
|
||||
comments, err := findCodeComments(ctx, opts, issue, currentUser, review, showOutdatedComments)
|
||||
comments, err := findCodeComments(ctx, opts, issue, doer, review, showOutdatedComments)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -47,7 +90,7 @@ func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *u
|
|||
return pathToLineToComment, nil
|
||||
}
|
||||
|
||||
func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issue, currentUser *user_model.User, review *Review, showOutdatedComments bool) ([]*Comment, error) {
|
||||
func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issue, doer *user_model.User, review *Review, showOutdatedComments bool) ([]*Comment, error) {
|
||||
var comments CommentList
|
||||
if review == nil {
|
||||
review = &Review{ID: 0}
|
||||
|
@ -91,7 +134,7 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
|
|||
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) {
|
||||
(doer == nil || doer.ID != re.ReviewerID) {
|
||||
continue
|
||||
}
|
||||
comment.Review = re
|
||||
|
@ -121,13 +164,14 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
|
|||
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, showOutdatedComments bool) ([]*Comment, error) {
|
||||
// FetchCodeConversation fetches the code conversation of a given comment (same review, treePath and line number)
|
||||
func FetchCodeConversation(ctx context.Context, comment *Comment, doer *user_model.User) ([]*Comment, error) {
|
||||
opts := FindCommentsOptions{
|
||||
Type: CommentTypeCode,
|
||||
IssueID: issue.ID,
|
||||
TreePath: treePath,
|
||||
Line: line,
|
||||
IssueID: comment.IssueID,
|
||||
ReviewID: comment.ReviewID,
|
||||
TreePath: comment.TreePath,
|
||||
Line: comment.Line,
|
||||
}
|
||||
return findCodeComments(ctx, opts, issue, currentUser, nil, showOutdatedComments)
|
||||
return findCodeComments(ctx, opts, comment.Issue, doer, nil, true)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue