diff --git a/src/vs/workbench/api/browser/mainThreadComments.ts b/src/vs/workbench/api/browser/mainThreadComments.ts index 658199aebaa..3f18e9c1a05 100644 --- a/src/vs/workbench/api/browser/mainThreadComments.ts +++ b/src/vs/workbench/api/browser/mainThreadComments.ts @@ -18,7 +18,7 @@ import { Extensions as PanelExtensions, PanelDescriptor, PanelRegistry } from 'v import { ICommentInfo, ICommentService } from 'vs/workbench/contrib/comments/browser/commentService'; import { CommentsPanel } from 'vs/workbench/contrib/comments/browser/commentsPanel'; import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; -import { CommentProviderFeatures, ExtHostCommentsShape, ExtHostContext, IExtHostContext, MainContext, MainThreadCommentsShape } from '../common/extHost.protocol'; +import { CommentProviderFeatures, ExtHostCommentsShape, ExtHostContext, IExtHostContext, MainContext, MainThreadCommentsShape, CommentThreadChanges } from '../common/extHost.protocol'; import { COMMENTS_PANEL_ID, COMMENTS_PANEL_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer'; @@ -116,17 +116,15 @@ export class MainThreadCommentThread implements modes.CommentThread { this._isDisposed = false; } - batchUpdate( - range: IRange, - label: string, - contextValue: string | undefined, - comments: modes.Comment[], - collapsibleState: modes.CommentThreadCollapsibleState) { - this._range = range; - this._label = label; - this._contextValue = contextValue; - this._comments = comments; - this._collapsibleState = collapsibleState; + batchUpdate(changes: CommentThreadChanges) { + const modified = (value: keyof CommentThreadChanges): boolean => + Object.prototype.hasOwnProperty.call(changes, value); + + if (modified('range')) { this._range = changes.range!; } + if (modified('label')) { this._label = changes.label; } + if (modified('contextValue')) { this._contextValue = changes.contextValue; } + if (modified('comments')) { this._comments = changes.comments; } + if (modified('collapseState')) { this._collapsibleState = changes.collapseState; } } dispose() { @@ -228,13 +226,9 @@ export class MainThreadCommentController { updateCommentThread(commentThreadHandle: number, threadId: string, resource: UriComponents, - range: IRange, - label: string, - contextValue: string | undefined, - comments: modes.Comment[], - collapsibleState: modes.CommentThreadCollapsibleState): void { + changes: CommentThreadChanges): void { let thread = this.getKnownThread(commentThreadHandle); - thread.batchUpdate(range, label, contextValue, comments, collapsibleState); + thread.batchUpdate(changes); this._commentService.updateComments(this._uniqueId, { added: [], @@ -430,18 +424,14 @@ export class MainThreadComments extends Disposable implements MainThreadComments commentThreadHandle: number, threadId: string, resource: UriComponents, - range: IRange, - label: string, - contextValue: string | undefined, - comments: modes.Comment[], - collapsibleState: modes.CommentThreadCollapsibleState): void { + changes: CommentThreadChanges): void { let provider = this._commentControllers.get(handle); if (!provider) { return undefined; } - return provider.updateCommentThread(commentThreadHandle, threadId, resource, range, label, contextValue, comments, collapsibleState); + return provider.updateCommentThread(commentThreadHandle, threadId, resource, changes); } $deleteCommentThread(handle: number, commentThreadHandle: number) { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 4bd9c9465de..b8f4e05cc2d 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -131,12 +131,20 @@ export interface CommentProviderFeatures { reactionHandler?: boolean; } +export type CommentThreadChanges = Partial<{ + range: IRange, + label: string, + contextValue: string, + comments: modes.Comment[], + collapseState: modes.CommentThreadCollapsibleState +}>; + export interface MainThreadCommentsShape extends IDisposable { $registerCommentController(handle: number, id: string, label: string): void; $unregisterCommentController(handle: number): void; $updateCommentControllerFeatures(handle: number, features: CommentProviderFeatures): void; $createCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, extensionId: ExtensionIdentifier): modes.CommentThread | undefined; - $updateCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, range: IRange, label: string | undefined, contextValue: string | undefined, comments: modes.Comment[], collapseState: modes.CommentThreadCollapsibleState): void; + $updateCommentThread(handle: number, commentThreadHandle: number, threadId: string, resource: UriComponents, changes: CommentThreadChanges): void; $deleteCommentThread(handle: number, commentThreadHandle: number): void; $onDidCommentThreadsChange(handle: number, event: modes.CommentThreadChangedEvent): void; } diff --git a/src/vs/workbench/api/common/extHostComments.ts b/src/vs/workbench/api/common/extHostComments.ts index 5fac49d7eda..20e85761638 100644 --- a/src/vs/workbench/api/common/extHostComments.ts +++ b/src/vs/workbench/api/common/extHostComments.ts @@ -16,7 +16,7 @@ import { ExtHostDocuments } from 'vs/workbench/api/common/extHostDocuments'; import * as extHostTypeConverter from 'vs/workbench/api/common/extHostTypeConverters'; import * as types from 'vs/workbench/api/common/extHostTypes'; import * as vscode from 'vscode'; -import { ExtHostCommentsShape, IMainContext, MainContext, MainThreadCommentsShape } from './extHost.protocol'; +import { ExtHostCommentsShape, IMainContext, MainContext, MainThreadCommentsShape, CommentThreadChanges } from './extHost.protocol'; import { ExtHostCommands } from './extHostCommands'; type ProviderHandle = number; @@ -213,12 +213,21 @@ export class ExtHostComments implements ExtHostCommentsShape, IDisposable { } } +type CommentThreadModification = Partial<{ + range: vscode.Range, + label: string | undefined, + contextValue: string | undefined, + comments: vscode.Comment[], + collapsibleState: vscode.CommentThreadCollapsibleState +}>; export class ExtHostCommentThread implements vscode.CommentThread { private static _handlePool: number = 0; readonly handle = ExtHostCommentThread._handlePool++; public commentHandle: number = 0; + private modifications: CommentThreadModification = Object.create(null); + set threadId(id: string) { this._id = id; } @@ -245,6 +254,7 @@ export class ExtHostCommentThread implements vscode.CommentThread { set range(range: vscode.Range) { if (!range.isEqual(this._range)) { this._range = range; + this.modifications.range = range; this._onDidUpdateCommentThread.fire(); } } @@ -261,6 +271,7 @@ export class ExtHostCommentThread implements vscode.CommentThread { set label(label: string | undefined) { this._label = label; + this.modifications.label = label; this._onDidUpdateCommentThread.fire(); } @@ -272,6 +283,7 @@ export class ExtHostCommentThread implements vscode.CommentThread { set contextValue(context: string | undefined) { this._contextValue = context; + this.modifications.contextValue = context; this._onDidUpdateCommentThread.fire(); } @@ -281,6 +293,7 @@ export class ExtHostCommentThread implements vscode.CommentThread { set comments(newComments: vscode.Comment[]) { this._comments = newComments; + this.modifications.comments = newComments; this._onDidUpdateCommentThread.fire(); } @@ -292,6 +305,7 @@ export class ExtHostCommentThread implements vscode.CommentThread { set collapsibleState(newState: vscode.CommentThreadCollapsibleState) { this._collapseState = newState; + this.modifications.collapsibleState = newState; this._onDidUpdateCommentThread.fire(); } @@ -353,22 +367,34 @@ export class ExtHostCommentThread implements vscode.CommentThread { this._acceptInputDisposables.value = new DisposableStore(); } - const commentThreadRange = extHostTypeConverter.Range.from(this._range); - const label = this.label; - const contextValue = this.contextValue; - const comments = this._comments.map(cmt => { return convertToModeComment(this, this._commentController, cmt, this._commentsMap); }); - const collapsibleState = convertToCollapsibleState(this._collapseState); + const modified = (value: keyof CommentThreadModification): boolean => + Object.prototype.hasOwnProperty.call(this.modifications, value); + + const formattedModifications: CommentThreadChanges = {}; + if (modified('range')) { + formattedModifications.range = extHostTypeConverter.Range.from(this._range); + } + if (modified('label')) { + formattedModifications.label = this.label; + } + if (modified('contextValue')) { + formattedModifications.contextValue = this.contextValue; + } + if (modified('comments')) { + formattedModifications.comments = + this._comments.map(cmt => convertToModeComment(this, this._commentController, cmt, this._commentsMap)); + } + if (modified('collapsibleState')) { + formattedModifications.collapseState = convertToCollapsibleState(this._collapseState); + } + this.modifications = {}; this._proxy.$updateCommentThread( this._commentController.handle, this.handle, this._id!, this._uri, - commentThreadRange, - label, - contextValue, - comments, - collapsibleState + formattedModifications ); } diff --git a/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts b/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts index 449b70fde69..a9030cb39c4 100644 --- a/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts +++ b/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts @@ -271,6 +271,7 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget } public collapse(): Promise { + this._commentThread.collapsibleState = modes.CommentThreadCollapsibleState.Collapsed; if (this._commentThread.comments && this._commentThread.comments.length === 0) { this.deleteCommentThread(); return Promise.resolve(); @@ -289,11 +290,13 @@ export class ReviewZoneWidget extends ZoneWidget implements ICommentThreadWidget toggleExpand(lineNumber: number) { if (this._isExpanded) { + this._commentThread.collapsibleState = modes.CommentThreadCollapsibleState.Collapsed; this.hide(); if (!this._commentThread.comments || !this._commentThread.comments.length) { this.deleteCommentThread(); } } else { + this._commentThread.collapsibleState = modes.CommentThreadCollapsibleState.Expanded; this.show({ lineNumber: lineNumber, column: 1 }, 2); } }