diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts index a1ae368dbe6..ec137f5bd5b 100644 --- a/src/vs/editor/common/modes.ts +++ b/src/vs/editor/common/modes.ts @@ -1253,6 +1253,7 @@ export interface CommentThread2 { threadId: string; resource: string; range: IRange; + label: string; comments: Comment[]; onDidChangeComments: Event; collapsibleState?: CommentThreadCollapsibleState; @@ -1261,6 +1262,7 @@ export interface CommentThread2 { acceptInputCommands: Command[]; onDidChangeAcceptInputCommands: Event; onDidChangeRange: Event; + onDidChangeLabel: Event; onDidChangeCollasibleState: Event; } @@ -1322,6 +1324,7 @@ export interface Comment { readonly deleteCommand?: Command; readonly isDraft?: boolean; readonly commentReactions?: CommentReaction[]; + readonly label?: string; } /** diff --git a/src/vs/vscode.proposed.d.ts b/src/vs/vscode.proposed.d.ts index a882a05d59f..5080793d34a 100644 --- a/src/vs/vscode.proposed.d.ts +++ b/src/vs/vscode.proposed.d.ts @@ -800,6 +800,11 @@ declare module 'vscode' { */ range: Range; + /** + * Label describing the [Comment Thread](#CommentThread) + */ + label?: string; + /** * The ordered comments of the thread. */ @@ -827,6 +832,11 @@ declare module 'vscode' { */ body: MarkdownString; + /** + * Label describing the [Comment](#Comment) + */ + label?: string; + /** * The display name of the user who created the comment */ diff --git a/src/vs/workbench/api/electron-browser/mainThreadComments.ts b/src/vs/workbench/api/electron-browser/mainThreadComments.ts index 7ef63a775e2..2f851f1e3bc 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadComments.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadComments.ts @@ -94,6 +94,20 @@ export class MainThreadCommentThread implements modes.CommentThread2 { private _onDidChangeInput = new Emitter(); get onDidChangeInput(): Event { return this._onDidChangeInput.event; } + private _label: string; + + get label(): string { + return this._label; + } + + set label(label: string) { + this._label = label; + } + + private _onDidChangeLabel = new Emitter(); + get onDidChangeLabel(): Event { return this._onDidChangeLabel.event; } + + public get comments(): modes.Comment[] { return this._comments; } @@ -263,6 +277,11 @@ export class MainThreadCommentController { thread.range = range; } + updateCommentThreadLabel(commentThreadHandle: number, label: string) { + let thread = this._threads.get(commentThreadHandle); + thread.label = label; + } + updateInput(input: string) { let thread = this.activeCommentThread; @@ -445,6 +464,16 @@ export class MainThreadComments extends Disposable implements MainThreadComments provider.updateCommentThreadRange(commentThreadHandle, range); } + $updateCommentThreadLabel(handle: number, commentThreadHandle: number, label: string): void { + let provider = this._commentControllers.get(handle); + + if (!provider) { + return; + } + + provider.updateCommentThreadLabel(commentThreadHandle, label); + } + $registerDocumentCommentProvider(handle: number, features: CommentProviderFeatures): void { this._documentProviders.set(handle, undefined); const handler = new MainThreadDocumentCommentProvider(this._proxy, handle, features); diff --git a/src/vs/workbench/api/node/extHost.protocol.ts b/src/vs/workbench/api/node/extHost.protocol.ts index 831c2bb46cc..5b6c038376c 100644 --- a/src/vs/workbench/api/node/extHost.protocol.ts +++ b/src/vs/workbench/api/node/extHost.protocol.ts @@ -127,6 +127,7 @@ export interface MainThreadCommentsShape extends IDisposable { $updateCommentThreadCommands(handle: number, commentThreadHandle: number, acceptInputCommands: modes.Command[]): void; $updateCommentThreadCollapsibleState(handle: number, commentThreadHandle: number, collapseState: modes.CommentThreadCollapsibleState): void; $updateCommentThreadRange(handle: number, commentThreadHandle: number, range: IRange): void; + $updateCommentThreadLabel(handle: number, commentThreadHandle: number, label: string): void; $registerDocumentCommentProvider(handle: number, features: CommentProviderFeatures): void; $unregisterDocumentCommentProvider(handle: number): void; $registerWorkspaceCommentProvider(handle: number, extensionId: ExtensionIdentifier): void; diff --git a/src/vs/workbench/api/node/extHostComments.ts b/src/vs/workbench/api/node/extHostComments.ts index c4555575aa4..4138ce9f911 100644 --- a/src/vs/workbench/api/node/extHostComments.ts +++ b/src/vs/workbench/api/node/extHostComments.ts @@ -308,6 +308,17 @@ export class ExtHostCommentThread implements vscode.CommentThread { return this._range; } + private _label: string; + + get label(): string { + return this._label; + } + + set label(label: string) { + this._label = label; + this._proxy.$updateCommentThreadLabel(this._commentControlHandle, this.handle, this._label); + } + private _comments: vscode.Comment[] = []; get comments(): vscode.Comment[] { @@ -557,7 +568,8 @@ function convertToModeComment(vscodeComment: vscode.Comment, commandsConverter: userIconPath: iconPath, isDraft: vscodeComment.isDraft, editCommand: vscodeComment.editCommand ? commandsConverter.toInternal(vscodeComment.editCommand) : undefined, - deleteCommand: vscodeComment.editCommand ? commandsConverter.toInternal(vscodeComment.deleteCommand) : undefined + deleteCommand: vscodeComment.editCommand ? commandsConverter.toInternal(vscodeComment.deleteCommand) : undefined, + label: vscodeComment.label }; } diff --git a/src/vs/workbench/contrib/comments/electron-browser/commentNode.ts b/src/vs/workbench/contrib/comments/electron-browser/commentNode.ts index 1ece57bc8d9..d809d163a50 100644 --- a/src/vs/workbench/contrib/comments/electron-browser/commentNode.ts +++ b/src/vs/workbench/contrib/comments/electron-browser/commentNode.ts @@ -508,7 +508,9 @@ export class CommentNode extends Disposable { this.comment = newComment; - if (newComment.isDraft) { + if (newComment.label) { + this._isPendingLabel.innerText = newComment.label; + } else if (newComment.isDraft) { this._isPendingLabel.innerText = 'Pending'; } else { this._isPendingLabel.innerText = ''; diff --git a/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts b/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts index 7cd60f65537..1a8c61cf255 100644 --- a/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts +++ b/src/vs/workbench/contrib/comments/electron-browser/commentThreadWidget.ts @@ -709,12 +709,18 @@ export class ReviewZoneWidget extends ZoneWidget { } private createThreadLabel() { - let label: string; - if (this._commentThread.comments.length) { - const participantsList = this._commentThread.comments.filter(arrays.uniqueFilter(comment => comment.userName)).map(comment => `@${comment.userName}`).join(', '); - label = nls.localize('commentThreadParticipants', "Participants: {0}", participantsList); - } else { - label = nls.localize('startThread', "Start discussion"); + let label: string | undefined; + if ((this._commentThread as modes.CommentThread2).commentThreadHandle !== undefined) { + label = (this._commentThread as modes.CommentThread2).label; + } + + if (label === undefined) { + if (this._commentThread.comments.length) { + const participantsList = this._commentThread.comments.filter(arrays.uniqueFilter(comment => comment.userName)).map(comment => `@${comment.userName}`).join(', '); + label = nls.localize('commentThreadParticipants', "Participants: {0}", participantsList); + } else { + label = nls.localize('startThread', "Start discussion"); + } } this._headingLabel.innerHTML = strings.escape(label);