@@ -14,15 +14,58 @@ import (
1414 "xorm.io/builder"
1515)
1616
17- // CodeComments represents comments on code by using this structure: FILENAME -> LINE (+ == proposed; - == previous) -> COMMENTS
18- type CodeComments map [string ]map [int64 ][]* Comment
17+ // CodeConversation contains the comment of a given review
18+ type CodeConversation []* Comment
19+
20+ // CodeConversationsAtLine contains the conversations for a given line
21+ type CodeConversationsAtLine map [int64 ][]CodeConversation
22+
23+ // CodeConversationsAtLineAndTreePath contains the conversations for a given TreePath and line
24+ type CodeConversationsAtLineAndTreePath map [string ]CodeConversationsAtLine
25+
26+ func newCodeConversationsAtLineAndTreePath (comments []* Comment ) CodeConversationsAtLineAndTreePath {
27+ tree := make (CodeConversationsAtLineAndTreePath )
28+ for _ , comment := range comments {
29+ tree .insertComment (comment )
30+ }
31+ return tree
32+ }
33+
34+ func (tree CodeConversationsAtLineAndTreePath ) insertComment (comment * Comment ) {
35+ // attempt to append comment to existing conversations (i.e. list of comments belonging to the same review)
36+ for i , conversation := range tree [comment.TreePath ][comment.Line ] {
37+ if conversation [0 ].ReviewID == comment .ReviewID {
38+ tree [comment.TreePath ][comment.Line ][i ] = append (conversation , comment )
39+ return
40+ }
41+ }
42+
43+ // no previous conversation was found at this line, create it
44+ if tree [comment .TreePath ] == nil {
45+ tree [comment .TreePath ] = make (map [int64 ][]CodeConversation )
46+ }
1947
20- // FetchCodeComments will return a 2d-map: ["Path"]["Line"] = Comments at line
21- func FetchCodeComments (ctx context.Context , issue * Issue , currentUser * user_model.User , showOutdatedComments bool ) (CodeComments , error ) {
22- return fetchCodeCommentsByReview (ctx , issue , currentUser , nil , showOutdatedComments )
48+ tree [comment.TreePath ][comment.Line ] = append (tree [comment.TreePath ][comment.Line ], CodeConversation {comment })
2349}
2450
25- func fetchCodeCommentsByReview (ctx context.Context , issue * Issue , currentUser * user_model.User , review * Review , showOutdatedComments bool ) (CodeComments , error ) {
51+ // FetchCodeConversations will return a 2d-map: ["Path"]["Line"] = List of CodeConversation (one per review) for this line
52+ func FetchCodeConversations (ctx context.Context , issue * Issue , doer * user_model.User , showOutdatedComments bool ) (CodeConversationsAtLineAndTreePath , error ) {
53+ opts := FindCommentsOptions {
54+ Type : CommentTypeCode ,
55+ IssueID : issue .ID ,
56+ }
57+ comments , err := findCodeComments (ctx , opts , issue , doer , nil , showOutdatedComments )
58+ if err != nil {
59+ return nil , err
60+ }
61+
62+ return newCodeConversationsAtLineAndTreePath (comments ), nil
63+ }
64+
65+ // CodeComments represents comments on code by using this structure: FILENAME -> LINE (+ == proposed; - == previous) -> COMMENTS
66+ type CodeComments map [string ]map [int64 ][]* Comment
67+
68+ func fetchCodeCommentsByReview (ctx context.Context , issue * Issue , doer * user_model.User , review * Review , showOutdatedComments bool ) (CodeComments , error ) {
2669 pathToLineToComment := make (CodeComments )
2770 if review == nil {
2871 review = & Review {ID : 0 }
@@ -33,7 +76,7 @@ func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *u
3376 ReviewID : review .ID ,
3477 }
3578
36- comments , err := findCodeComments (ctx , opts , issue , currentUser , review , showOutdatedComments )
79+ comments , err := findCodeComments (ctx , opts , issue , doer , review , showOutdatedComments )
3780 if err != nil {
3881 return nil , err
3982 }
@@ -47,7 +90,7 @@ func fetchCodeCommentsByReview(ctx context.Context, issue *Issue, currentUser *u
4790 return pathToLineToComment , nil
4891}
4992
50- func findCodeComments (ctx context.Context , opts FindCommentsOptions , issue * Issue , currentUser * user_model.User , review * Review , showOutdatedComments bool ) ([]* Comment , error ) {
93+ func findCodeComments (ctx context.Context , opts FindCommentsOptions , issue * Issue , doer * user_model.User , review * Review , showOutdatedComments bool ) ([]* Comment , error ) {
5194 var comments CommentList
5295 if review == nil {
5396 review = & Review {ID : 0 }
@@ -91,7 +134,7 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
91134 if re , ok := reviews [comment .ReviewID ]; ok && re != nil {
92135 // If the review is pending only the author can see the comments (except if the review is set)
93136 if review .ID == 0 && re .Type == ReviewTypePending &&
94- (currentUser == nil || currentUser .ID != re .ReviewerID ) {
137+ (doer == nil || doer .ID != re .ReviewerID ) {
95138 continue
96139 }
97140 comment .Review = re
@@ -121,13 +164,14 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
121164 return comments [:n ], nil
122165}
123166
124- // FetchCodeCommentsByLine fetches the code comments for a given treePath and line number
125- func FetchCodeCommentsByLine (ctx context.Context , issue * Issue , currentUser * user_model.User , treePath string , line int64 , showOutdatedComments bool ) ([]* Comment , error ) {
167+ // FetchCodeConversation fetches the code conversation of a given comment (same review, treePath and line number)
168+ func FetchCodeConversation (ctx context.Context , comment * Comment , doer * user_model.User ) ([]* Comment , error ) {
126169 opts := FindCommentsOptions {
127170 Type : CommentTypeCode ,
128- IssueID : issue .ID ,
129- TreePath : treePath ,
130- Line : line ,
171+ IssueID : comment .IssueID ,
172+ ReviewID : comment .ReviewID ,
173+ TreePath : comment .TreePath ,
174+ Line : comment .Line ,
131175 }
132- return findCodeComments (ctx , opts , issue , currentUser , nil , showOutdatedComments )
176+ return findCodeComments (ctx , opts , comment . Issue , doer , nil , true )
133177}
0 commit comments