@@ -23,6 +23,7 @@ import { ReviewManager } from '../view/reviewManager';
23
23
export class PullRequestViewProvider extends WebviewViewBase implements vscode . WebviewViewProvider {
24
24
public override readonly viewType = 'github:activePullRequest' ;
25
25
private _existingReviewers : ReviewState [ ] = [ ] ;
26
+ private _isUpdating : boolean = false ;
26
27
27
28
constructor (
28
29
extensionUri : vscode . Uri ,
@@ -182,132 +183,143 @@ export class PullRequestViewProvider extends WebviewViewBase implements vscode.W
182
183
disposeAll ( this . _prDisposables ) ;
183
184
}
184
185
this . _prDisposables = [ ] ;
185
- this . _prDisposables . push ( pullRequestModel . onDidChange ( ( ) => this . updatePullRequest ( pullRequestModel ) ) ) ;
186
+ this . _prDisposables . push ( pullRequestModel . onDidChange ( e => {
187
+ if ( ( e . state || e . comments || e . reviewers ) && ! this . _isUpdating ) {
188
+ this . updatePullRequest ( pullRequestModel ) ;
189
+ }
190
+ } ) ) ;
186
191
this . _prDisposables . push ( pullRequestModel . onDidChangePendingReviewState ( ( ) => this . updatePullRequest ( pullRequestModel ) ) ) ;
187
192
}
188
193
189
194
private _updatePendingVisibility : vscode . Disposable | undefined = undefined ;
190
195
public async updatePullRequest ( pullRequestModel : PullRequestModel ) : Promise < void > {
191
- if ( this . _view && ! this . _view . visible ) {
192
- this . _updatePendingVisibility ?. dispose ( ) ;
193
- this . _updatePendingVisibility = this . _view . onDidChangeVisibility ( async ( ) => {
194
- this . updatePullRequest ( pullRequestModel ) ;
195
- this . _updatePendingVisibility ?. dispose ( ) ;
196
- } ) ;
196
+ if ( this . _isUpdating ) {
197
+ throw new Error ( 'Already updating pull request view' ) ;
197
198
}
199
+ this . _isUpdating = true ;
198
200
199
- if ( ( this . _prDisposables === undefined ) || ( pullRequestModel . number !== this . _item . number ) ) {
200
- this . registerPrSpecificListeners ( pullRequestModel ) ;
201
- }
202
- this . _item = pullRequestModel ;
203
- return Promise . all ( [
204
- this . _folderRepositoryManager . resolvePullRequest (
205
- pullRequestModel . remote . owner ,
206
- pullRequestModel . remote . repositoryName ,
207
- pullRequestModel . number ,
208
- ) ,
209
- this . _folderRepositoryManager . getPullRequestRepositoryAccessAndMergeMethods ( pullRequestModel ) ,
210
- pullRequestModel . getTimelineEvents ( ) ,
211
- pullRequestModel . getReviewRequests ( ) ,
212
- this . _folderRepositoryManager . getBranchNameForPullRequest ( pullRequestModel ) ,
213
- this . _folderRepositoryManager . getPullRequestRepositoryDefaultBranch ( pullRequestModel ) ,
214
- this . _folderRepositoryManager . getCurrentUser ( pullRequestModel . githubRepository ) ,
215
- pullRequestModel . canEdit ( ) ,
216
- pullRequestModel . validateDraftMode ( ) ,
217
- ensureEmojis ( this . _folderRepositoryManager . context )
218
- ] )
219
- . then ( result => {
220
- const [ pullRequest , repositoryAccess , timelineEvents , requestedReviewers , branchInfo , defaultBranch , currentUser , viewerCanEdit , hasReviewDraft ] = result ;
221
- if ( ! pullRequest ) {
222
- throw new Error (
223
- `Fail to resolve Pull Request #${ pullRequestModel . number } in ${ pullRequestModel . remote . owner } /${ pullRequestModel . remote . repositoryName } ` ,
224
- ) ;
225
- }
201
+ try {
202
+ if ( this . _view && ! this . _view . visible ) {
203
+ this . _updatePendingVisibility ?. dispose ( ) ;
204
+ this . _updatePendingVisibility = this . _view . onDidChangeVisibility ( async ( ) => {
205
+ this . updatePullRequest ( pullRequestModel ) ;
206
+ this . _updatePendingVisibility ?. dispose ( ) ;
207
+ } ) ;
208
+ }
226
209
227
- this . _item = pullRequest ;
228
- if ( ! this . _view ) {
229
- // If the there is no PR webview, then there is nothing else to update.
230
- return ;
231
- }
210
+ if ( ( this . _prDisposables === undefined ) || ( pullRequestModel . number !== this . _item . number ) ) {
211
+ this . registerPrSpecificListeners ( pullRequestModel ) ;
212
+ }
213
+ this . _item = pullRequestModel ;
214
+ const [ pullRequest , repositoryAccess , timelineEvents , requestedReviewers , branchInfo , defaultBranch , currentUser , viewerCanEdit , hasReviewDraft ] = await Promise . all ( [
215
+ this . _folderRepositoryManager . resolvePullRequest (
216
+ pullRequestModel . remote . owner ,
217
+ pullRequestModel . remote . repositoryName ,
218
+ pullRequestModel . number ,
219
+ ) ,
220
+ this . _folderRepositoryManager . getPullRequestRepositoryAccessAndMergeMethods ( pullRequestModel ) ,
221
+ pullRequestModel . getTimelineEvents ( ) ,
222
+ pullRequestModel . getReviewRequests ( ) ,
223
+ this . _folderRepositoryManager . getBranchNameForPullRequest ( pullRequestModel ) ,
224
+ this . _folderRepositoryManager . getPullRequestRepositoryDefaultBranch ( pullRequestModel ) ,
225
+ this . _folderRepositoryManager . getCurrentUser ( pullRequestModel . githubRepository ) ,
226
+ pullRequestModel . canEdit ( ) ,
227
+ pullRequestModel . validateDraftMode ( ) ,
228
+ ensureEmojis ( this . _folderRepositoryManager . context )
229
+ ] ) ;
230
+
231
+ if ( ! pullRequest ) {
232
+ throw new Error (
233
+ `Fail to resolve Pull Request #${ pullRequestModel . number } in ${ pullRequestModel . remote . owner } /${ pullRequestModel . remote . repositoryName } ` ,
234
+ ) ;
235
+ }
232
236
233
- try {
234
- this . _view . title = ` ${ vscode . l10n . t ( 'Review Pull Request' ) } # ${ pullRequestModel . number . toString ( ) } ` ;
235
- } catch ( e ) {
236
- // If we ry to set the title of the webview too early it will throw an error.
237
- }
237
+ this . _item = pullRequest ;
238
+ if ( ! this . _view ) {
239
+ // If the there is no PR webview, then there is nothing else to update.
240
+ return ;
241
+ }
238
242
239
- const isCurrentlyCheckedOut = pullRequestModel . equals ( this . _folderRepositoryManager . activePullRequest ) ;
240
- const hasWritePermission = repositoryAccess ! . hasWritePermission ;
241
- const mergeMethodsAvailability = repositoryAccess ! . mergeMethodsAvailability ;
242
- const canEdit = hasWritePermission || viewerCanEdit ;
243
- const defaultMergeMethod = getDefaultMergeMethod ( mergeMethodsAvailability ) ;
244
- this . _existingReviewers = parseReviewers (
245
- requestedReviewers ?? [ ] ,
246
- timelineEvents ?? [ ] ,
247
- pullRequest . author ,
248
- ) ;
243
+ try {
244
+ this . _view . title = `${ vscode . l10n . t ( 'Review Pull Request' ) } #${ pullRequestModel . number . toString ( ) } ` ;
245
+ } catch ( e ) {
246
+ // If we ry to set the title of the webview too early it will throw an error.
247
+ }
249
248
250
- const isCrossRepository =
251
- pullRequest . base &&
252
- pullRequest . head &&
253
- ! pullRequest . base . repositoryCloneUrl . equals ( pullRequest . head . repositoryCloneUrl ) ;
254
-
255
- const continueOnGitHub = ! ! ( isCrossRepository && isInCodespaces ( ) ) ;
256
- const reviewState = this . getCurrentUserReviewState ( this . _existingReviewers , currentUser ) ;
257
-
258
- const context : Partial < PullRequest > = {
259
- number : pullRequest . number ,
260
- title : pullRequest . title ,
261
- url : pullRequest . html_url ,
262
- createdAt : pullRequest . createdAt ,
263
- body : pullRequest . body ,
264
- bodyHTML : pullRequest . bodyHTML ,
265
- labels : pullRequest . item . labels . map ( label => ( { ...label , displayName : emojify ( label . name ) } ) ) ,
266
- author : {
267
- login : pullRequest . author . login ,
268
- name : pullRequest . author . name ,
269
- avatarUrl : pullRequest . userAvatar ,
270
- url : pullRequest . author . url ,
271
- email : pullRequest . author . email ,
272
- id : pullRequest . author . id ,
273
- accountType : pullRequest . author . accountType ,
274
- } ,
275
- state : pullRequest . state ,
276
- isCurrentlyCheckedOut : isCurrentlyCheckedOut ,
277
- isRemoteBaseDeleted : pullRequest . isRemoteBaseDeleted ,
278
- base : pullRequest . base . label ,
279
- isRemoteHeadDeleted : pullRequest . isRemoteHeadDeleted ,
280
- isLocalHeadDeleted : ! branchInfo ,
281
- head : pullRequest . head ?. label ?? '' ,
282
- canEdit : canEdit ,
283
- hasWritePermission,
284
- mergeable : pullRequest . item . mergeable ,
285
- isDraft : pullRequest . isDraft ,
286
- status : null ,
287
- reviewRequirement : null ,
288
- canUpdateBranch : pullRequest . item . viewerCanUpdate ,
289
- events : timelineEvents ,
290
- mergeMethodsAvailability,
291
- defaultMergeMethod,
292
- repositoryDefaultBranch : defaultBranch ,
293
- isIssue : false ,
294
- isAuthor : currentUser . login === pullRequest . author . login ,
295
- reviewers : this . _existingReviewers ,
296
- continueOnGitHub,
297
- isDarkTheme : vscode . window . activeColorTheme . kind === vscode . ColorThemeKind . Dark ,
298
- isEnterprise : pullRequest . githubRepository . remote . isEnterprise ,
299
- hasReviewDraft,
300
- currentUserReviewState : reviewState
301
- } ;
302
-
303
- this . _postMessage ( {
304
- command : 'pr.initialize' ,
305
- pullrequest : context ,
306
- } ) ;
307
- } )
308
- . catch ( e => {
309
- vscode . window . showErrorMessage ( `Error updating active pull request view: ${ formatError ( e ) } ` ) ;
249
+ const isCurrentlyCheckedOut = pullRequestModel . equals ( this . _folderRepositoryManager . activePullRequest ) ;
250
+ const hasWritePermission = repositoryAccess ! . hasWritePermission ;
251
+ const mergeMethodsAvailability = repositoryAccess ! . mergeMethodsAvailability ;
252
+ const canEdit = hasWritePermission || viewerCanEdit ;
253
+ const defaultMergeMethod = getDefaultMergeMethod ( mergeMethodsAvailability ) ;
254
+ this . _existingReviewers = parseReviewers (
255
+ requestedReviewers ?? [ ] ,
256
+ timelineEvents ?? [ ] ,
257
+ pullRequest . author ,
258
+ ) ;
259
+
260
+ const isCrossRepository =
261
+ pullRequest . base &&
262
+ pullRequest . head &&
263
+ ! pullRequest . base . repositoryCloneUrl . equals ( pullRequest . head . repositoryCloneUrl ) ;
264
+
265
+ const continueOnGitHub = ! ! ( isCrossRepository && isInCodespaces ( ) ) ;
266
+ const reviewState = this . getCurrentUserReviewState ( this . _existingReviewers , currentUser ) ;
267
+
268
+ const context : Partial < PullRequest > = {
269
+ number : pullRequest . number ,
270
+ title : pullRequest . title ,
271
+ url : pullRequest . html_url ,
272
+ createdAt : pullRequest . createdAt ,
273
+ body : pullRequest . body ,
274
+ bodyHTML : pullRequest . bodyHTML ,
275
+ labels : pullRequest . item . labels . map ( label => ( { ...label , displayName : emojify ( label . name ) } ) ) ,
276
+ author : {
277
+ login : pullRequest . author . login ,
278
+ name : pullRequest . author . name ,
279
+ avatarUrl : pullRequest . userAvatar ,
280
+ url : pullRequest . author . url ,
281
+ email : pullRequest . author . email ,
282
+ id : pullRequest . author . id ,
283
+ accountType : pullRequest . author . accountType ,
284
+ } ,
285
+ state : pullRequest . state ,
286
+ isCurrentlyCheckedOut : isCurrentlyCheckedOut ,
287
+ isRemoteBaseDeleted : pullRequest . isRemoteBaseDeleted ,
288
+ base : pullRequest . base . label ,
289
+ isRemoteHeadDeleted : pullRequest . isRemoteHeadDeleted ,
290
+ isLocalHeadDeleted : ! branchInfo ,
291
+ head : pullRequest . head ?. label ?? '' ,
292
+ canEdit : canEdit ,
293
+ hasWritePermission,
294
+ mergeable : pullRequest . item . mergeable ,
295
+ isDraft : pullRequest . isDraft ,
296
+ status : null ,
297
+ reviewRequirement : null ,
298
+ canUpdateBranch : pullRequest . item . viewerCanUpdate ,
299
+ events : timelineEvents ,
300
+ mergeMethodsAvailability,
301
+ defaultMergeMethod,
302
+ repositoryDefaultBranch : defaultBranch ,
303
+ isIssue : false ,
304
+ isAuthor : currentUser . login === pullRequest . author . login ,
305
+ reviewers : this . _existingReviewers ,
306
+ continueOnGitHub,
307
+ isDarkTheme : vscode . window . activeColorTheme . kind === vscode . ColorThemeKind . Dark ,
308
+ isEnterprise : pullRequest . githubRepository . remote . isEnterprise ,
309
+ hasReviewDraft,
310
+ currentUserReviewState : reviewState
311
+ } ;
312
+
313
+ this . _postMessage ( {
314
+ command : 'pr.initialize' ,
315
+ pullrequest : context ,
310
316
} ) ;
317
+
318
+ } catch ( e ) {
319
+ vscode . window . showErrorMessage ( `Error updating active pull request view: ${ formatError ( e ) } ` ) ;
320
+ } finally {
321
+ this . _isUpdating = false ;
322
+ }
311
323
}
312
324
313
325
private close ( message : IRequestMessage < string > ) : void {
0 commit comments