@@ -7,7 +7,7 @@ import * as path from 'path';
77import * as vscode from 'vscode' ;
88import { parseDiff } from '../common/diffHunk' ;
99import { getDiffLineByPosition , getLastDiffLine , mapCommentsToHead , mapHeadLineToDiffHunkPosition , mapOldPositionToNew , getZeroBased , getAbsolutePosition } from '../common/diffPositionMapping' ;
10- import { toReviewUri , fromReviewUri } from '../common/uri' ;
10+ import { toReviewUri , fromReviewUri , fromPRUri } from '../common/uri' ;
1111import { groupBy , formatError } from '../common/utils' ;
1212import { Comment } from '../common/comment' ;
1313import { GitChangeType , SlimFileChange } from '../common/file' ;
@@ -21,6 +21,7 @@ import { FileChangeNode, RemoteFileChangeNode, fileChangeNodeFilter } from './tr
2121import Logger from '../common/logger' ;
2222import { PullRequestsTreeDataProvider } from './prsTreeDataProvider' ;
2323import { IConfiguration } from '../authentication/configuration' ;
24+ import { providePRDocumentComments } from './treeNodes/pullRequestNode' ;
2425
2526export class ReviewManager implements vscode . DecorationProvider {
2627 private static _instance : ReviewManager ;
@@ -176,16 +177,50 @@ export class ReviewManager implements vscode.DecorationProvider {
176177 vscode . commands . executeCommand ( 'pr.refreshList' ) ;
177178 }
178179
180+ private findMatchedFileByUri ( document : vscode . TextDocument ) : FileChangeNode {
181+ const uri = document . uri ;
182+
183+ let fileName : string ;
184+ if ( uri . scheme === 'review' || uri . scheme === 'file' ) {
185+ fileName = uri . path ;
186+ }
187+
188+ if ( uri . scheme === 'pr' ) {
189+ fileName = fromPRUri ( uri ) . fileName ;
190+ }
191+
192+ const matchedFiles = fileChangeNodeFilter ( this . _localFileChanges ) . filter ( fileChange => {
193+ if ( uri . scheme === 'review' || uri . scheme === 'pr' ) {
194+ return fileChange . fileName === fileName ;
195+ } else {
196+ let absoluteFilePath = vscode . Uri . file ( path . resolve ( this . _repository . path , fileChange . fileName ) ) ;
197+ let targetFilePath = vscode . Uri . file ( fileName ) ;
198+ return absoluteFilePath . fsPath === targetFilePath . fsPath ;
199+ }
200+ } ) ;
201+
202+ if ( matchedFiles && matchedFiles . length ) {
203+ return matchedFiles [ 0 ] ;
204+ }
205+ }
206+
179207 private async replyToCommentThread ( document : vscode . TextDocument , range : vscode . Range , thread : vscode . CommentThread , text : string ) {
180208 try {
181- let ret = await this . _prManager . createCommentReply ( this . _prManager . activePullRequest , text , thread . threadId ) ;
209+ const matchedFile = this . findMatchedFileByUri ( document ) ;
210+ if ( ! matchedFile ) {
211+ throw new Error ( 'Unable to find matching file' ) ;
212+ }
213+
214+ const comment = await this . _prManager . createCommentReply ( this . _prManager . activePullRequest , text , thread . threadId ) ;
182215 thread . comments . push ( {
183- commentId : ret . data . id ,
184- body : new vscode . MarkdownString ( ret . data . body ) ,
185- userName : ret . data . user . login ,
186- gravatar : ret . data . user . avatar_url
216+ commentId : comment . id ,
217+ body : new vscode . MarkdownString ( comment . body ) ,
218+ userName : comment . user . login ,
219+ gravatar : comment . user . avatar_url
187220 } ) ;
188221
222+ matchedFile . comments . push ( comment ) ;
223+
189224 setTimeout ( ( ) => {
190225 this . updateComments ( ) ;
191226 } , 0 ) ;
@@ -197,56 +232,43 @@ export class ReviewManager implements vscode.DecorationProvider {
197232
198233 private async createNewCommentThread ( document : vscode . TextDocument , range : vscode . Range , text : string ) {
199234 try {
200- let uri = document . uri ;
201- let fileName = uri . path ;
202- let matchedFiles = fileChangeNodeFilter ( this . _localFileChanges ) . filter ( fileChange => {
203- if ( uri . scheme === 'review' ) {
204- return fileChange . fileName === fileName ;
205- } else {
206- let absoluteFilePath = vscode . Uri . file ( path . resolve ( this . _repository . path , fileChange . fileName ) ) ;
207- let targetFilePath = vscode . Uri . file ( fileName ) ;
208- return absoluteFilePath . fsPath === targetFilePath . fsPath ;
209- }
210- } ) ;
211-
235+ const uri = document . uri ;
236+ const matchedFile = this . findMatchedFileByUri ( document ) ;
237+ const query = uri . query === '' ? undefined : JSON . parse ( uri . query ) ;
238+ const isBase = query && query . base ;
212239
213- let query = uri . query === '' ? undefined : JSON . parse ( uri . query ) ;
240+ // git diff sha -- fileName
241+ const contentDiff = await this . _repository . diff ( matchedFile . fileName , this . _lastCommitSha ) ;
242+ const position = mapHeadLineToDiffHunkPosition ( matchedFile . diffHunks , contentDiff , range . start . line + 1 , isBase ) ;
214243
215- let isBase = query && query . base ;
216-
217- if ( matchedFiles && matchedFiles . length ) {
218- let matchedFile = matchedFiles [ 0 ] ;
219- // git diff sha -- fileName
220- let contentDiff = await this . _repository . diff ( matchedFile . fileName , this . _lastCommitSha ) ;
221- let position = mapHeadLineToDiffHunkPosition ( matchedFile . diffHunks , contentDiff , range . start . line + 1 , isBase ) ;
244+ if ( position < 0 ) {
245+ throw new Error ( 'Comment position cannot be negative' ) ;
246+ }
222247
223- if ( position < 0 ) {
224- return ;
225- }
248+ // there is no thread Id, which means it's a new thread
249+ let rawComment = await this . _prManager . createComment ( this . _prManager . activePullRequest , text , matchedFile . fileName , position ) ;
226250
227- // there is no thread Id, which means it's a new thread
228- let ret = await this . _prManager . createComment ( this . _prManager . activePullRequest , text , matchedFile . fileName , position ) ;
251+ let comment = {
252+ commentId : rawComment . id ,
253+ body : new vscode . MarkdownString ( rawComment . body ) ,
254+ userName : rawComment . user . login ,
255+ gravatar : rawComment . user . avatar_url
256+ } ;
229257
230- let comment = {
231- commentId : ret . data . id ,
232- body : new vscode . MarkdownString ( ret . data . body ) ,
233- userName : ret . data . user . login ,
234- gravatar : ret . data . user . avatar_url
235- } ;
258+ let commentThread : vscode . CommentThread = {
259+ threadId : comment . commentId ,
260+ resource : uri ,
261+ range : range ,
262+ comments : [ comment ]
263+ } ;
236264
237- let commentThread : vscode . CommentThread = {
238- threadId : comment . commentId ,
239- resource : uri ,
240- range : range ,
241- comments : [ comment ]
242- } ;
265+ matchedFile . comments . push ( rawComment ) ;
243266
244- setTimeout ( ( ) => {
245- this . updateComments ( ) ;
246- } , 0 ) ;
267+ setTimeout ( ( ) => {
268+ this . updateComments ( ) ;
269+ } , 0 ) ;
247270
248- return commentThread ;
249- }
271+ return commentThread ;
250272 } catch ( e ) {
251273 throw new Error ( formatError ( e ) ) ;
252274 }
@@ -579,6 +601,10 @@ export class ReviewManager implements vscode.DecorationProvider {
579601 } ;
580602 }
581603
604+ if ( document . uri . scheme === 'pr' ) {
605+ return providePRDocumentComments ( document , this . _prNumber , this . _localFileChanges ) ;
606+ }
607+
582608 if ( document . uri . scheme === 'review' ) {
583609 // we should check whehter the docuemnt is original or modified.
584610 let query = fromReviewUri ( document . uri ) ;
0 commit comments