From 94a643c9a67d7ad8488516ad8530500f40ec4ab1 Mon Sep 17 00:00:00 2001 From: Alex Ross Date: Wed, 10 Aug 2022 17:02:53 +0200 Subject: [PATCH] Update comment thread context menu proposal Part of #151533 --- src/vs/platform/actions/common/actions.ts | 3 +- .../contrib/comments/browser/commentMenus.ts | 8 +++- .../contrib/comments/browser/commentNode.ts | 42 +++++++++++++++---- .../comments/browser/commentThreadHeader.ts | 30 ++++++++++++- .../comments/browser/commentThreadWidget.ts | 30 ++----------- .../actions/common/menusExtensionPoint.ts | 14 +++++-- .../common/extensionsApiProposals.ts | 2 +- ...e.proposed.contribCommentPeekContext.d.ts} | 2 +- 8 files changed, 85 insertions(+), 46 deletions(-) rename src/vscode-dts/{vscode.proposed.contribCommentWidgetContext.d.ts => vscode.proposed.contribCommentPeekContext.d.ts} (88%) diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 143946f0e88b5..931aad80e3c02 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -124,7 +124,8 @@ export class MenuId { static readonly ViewTitleContext = new MenuId('ViewTitleContext'); static readonly CommentThreadTitle = new MenuId('CommentThreadTitle'); static readonly CommentThreadActions = new MenuId('CommentThreadActions'); - static readonly CommentThreadWidgetContext = new MenuId('CommentThreadWidgetContext'); + static readonly CommentThreadTitleContext = new MenuId('CommentThreadTitleContext'); + static readonly CommentThreadCommentContext = new MenuId('CommentThreadCommentContext'); static readonly CommentTitle = new MenuId('CommentTitle'); static readonly CommentActions = new MenuId('CommentActions'); static readonly InteractiveToolbar = new MenuId('InteractiveToolbar'); diff --git a/src/vs/workbench/contrib/comments/browser/commentMenus.ts b/src/vs/workbench/contrib/comments/browser/commentMenus.ts index dcc51f291f7de..79e647f91213e 100644 --- a/src/vs/workbench/contrib/comments/browser/commentMenus.ts +++ b/src/vs/workbench/contrib/comments/browser/commentMenus.ts @@ -31,8 +31,12 @@ export class CommentMenus implements IDisposable { return this.getMenu(MenuId.CommentActions, contextKeyService); } - getCommentThreadWidgetContextActions(contextKeyService: IContextKeyService): IMenu { - return this.getMenu(MenuId.CommentThreadWidgetContext, contextKeyService); + getCommentThreadTitleContextActions(contextKeyService: IContextKeyService): IMenu { + return this.getMenu(MenuId.CommentThreadTitleContext, contextKeyService); + } + + getCommentThreadCommentContextActions(contextKeyService: IContextKeyService): IMenu { + return this.getMenu(MenuId.CommentThreadCommentContext, contextKeyService); } private getMenu(menuId: MenuId, contextKeyService: IContextKeyService): IMenu { diff --git a/src/vs/workbench/contrib/comments/browser/commentNode.ts b/src/vs/workbench/contrib/comments/browser/commentNode.ts index a9b5e980e4b30..df7f71d462a8e 100644 --- a/src/vs/workbench/contrib/comments/browser/commentNode.ts +++ b/src/vs/workbench/contrib/comments/browser/commentNode.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import * as dom from 'vs/base/browser/dom'; import * as languages from 'vs/editor/common/languages'; import { ActionsOrientation, ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { Action, IActionRunner, IAction, Separator } from 'vs/base/common/actions'; +import { Action, IActionRunner, IAction, Separator, ActionRunner } from 'vs/base/common/actions'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { URI } from 'vs/base/common/uri'; import { ITextModel } from 'vs/editor/common/model'; @@ -40,6 +40,7 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { IMarkdownString } from 'vs/base/common/htmlContent'; import { IRange } from 'vs/editor/common/core/range'; import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange'; +import { CommentMenus } from 'vs/workbench/contrib/comments/browser/commentMenus'; export class CommentNode extends Disposable { private _domNode: HTMLElement; @@ -62,6 +63,7 @@ export class CommentNode extends Disposable { private _timestampWidget: TimestampWidget | undefined; private _contextKeyService: IContextKeyService; private _commentContextValue: IContextKey; + private _commentMenus: CommentMenus; protected actionRunner?: IActionRunner; protected toolbar: ToolBar | undefined; @@ -97,6 +99,7 @@ export class CommentNode extends Disposable { this._domNode = dom.$('div.review-comment'); this._contextKeyService = contextKeyService.createScoped(this._domNode); this._commentContextValue = this._contextKeyService.createKey('comment', comment.contextValue); + this._commentMenus = this.commentService.getCommentMenus(this.owner); this._domNode.tabIndex = -1; const avatar = dom.append(this._domNode, dom.$('div.avatar-container')); @@ -121,6 +124,10 @@ export class CommentNode extends Disposable { this._clearTimeout = null; this._register(dom.addDisposableListener(this._domNode, dom.EventType.CLICK, () => this.isEditing || this._onDidClick.fire(this))); + this._register(dom.addDisposableListener(this._domNode, dom.EventType.CONTEXT_MENU, e => { + return this.onContextMenu(e); + })); + } private updateCommentBody(body: string | IMarkdownString) { @@ -190,6 +197,14 @@ export class CommentNode extends Disposable { return result; } + private get commentNodeContext() { + return { + thread: this.commentThread, + commentUniqueId: this.comment.uniqueIdInThread, + $mid: MarshalledId.CommentNode + }; + } + private createToolbar() { this.toolbar = new ToolBar(this._actionsToolbarContainer, this.contextMenuService, { actionViewItemProvider: action => { @@ -211,11 +226,7 @@ export class CommentNode extends Disposable { orientation: ActionsOrientation.HORIZONTAL }); - this.toolbar.context = { - thread: this.commentThread, - commentUniqueId: this.comment.uniqueIdInThread, - $mid: MarshalledId.CommentNode - }; + this.toolbar.context = this.commentNodeContext; this.registerActionBarListeners(this._actionsToolbarContainer); this._register(this.toolbar); @@ -231,8 +242,7 @@ export class CommentNode extends Disposable { actions.push(toggleReactionAction); } - const commentMenus = this.commentService.getCommentMenus(this.owner); - const menu = commentMenus.getCommentTitleActions(this.comment, this._contextKeyService); + const menu = this._commentMenus.getCommentTitleActions(this.comment, this._contextKeyService); this._register(menu); this._register(menu.onDidChange(e => { const { primary, secondary } = this.getToolbarActions(menu); @@ -562,6 +572,22 @@ export class CommentNode extends Disposable { } } + + private onContextMenu(e: MouseEvent) { + const actions = this._commentMenus.getCommentThreadCommentContextActions(this._contextKeyService).getActions({ shouldForwardArgs: true }).map((value) => value[1]).flat(); + if (!actions.length) { + return; + } + this.contextMenuService.showContextMenu({ + getAnchor: () => e, + getActions: () => actions, + actionRunner: new ActionRunner(), + getActionsContext: () => { + return this.commentNodeContext; + }, + }); + } + focus() { this.domNode.focus(); if (!this._clearTimeout) { diff --git a/src/vs/workbench/contrib/comments/browser/commentThreadHeader.ts b/src/vs/workbench/contrib/comments/browser/commentThreadHeader.ts index ec2d56e230eda..161d50ba555bf 100644 --- a/src/vs/workbench/contrib/comments/browser/commentThreadHeader.ts +++ b/src/vs/workbench/contrib/comments/browser/commentThreadHeader.ts @@ -5,7 +5,7 @@ import * as dom from 'vs/base/browser/dom'; import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar'; -import { Action } from 'vs/base/common/actions'; +import { Action, ActionRunner } from 'vs/base/common/actions'; import { Codicon } from 'vs/base/common/codicons'; import { Disposable } from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; @@ -19,6 +19,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti import { registerIcon } from 'vs/platform/theme/common/iconRegistry'; import { ThemeIcon } from 'vs/platform/theme/common/themeService'; import { CommentMenus } from 'vs/workbench/contrib/comments/browser/commentMenus'; +import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; +import { MarshalledId } from 'vs/base/common/marshallingIds'; const collapseIcon = registerIcon('review-comment-collapse', Codicon.chevronUp, nls.localize('collapseIcon', 'Icon to collapse a review comment.')); const COLLAPSE_ACTION_CLASS = 'expand-review-action ' + ThemeIcon.asClassName(collapseIcon); @@ -36,7 +38,8 @@ export class CommentThreadHeader extends Disposable { private _commentMenus: CommentMenus, private _commentThread: languages.CommentThread, private _contextKeyService: IContextKeyService, - private instantiationService: IInstantiationService + private instantiationService: IInstantiationService, + private _contextMenuService: IContextMenuService ) { super(); this._headElement = dom.$('.head'); @@ -67,6 +70,10 @@ export class CommentThreadHeader extends Disposable { this.setActionBarActions(menu); })); + this._register(dom.addDisposableListener(this._headElement, dom.EventType.CONTEXT_MENU, e => { + return this.onContextMenu(e); + })); + this._actionbarWidget.context = this._commentThread; } @@ -103,4 +110,23 @@ export class CommentThreadHeader extends Disposable { this._headElement.style.height = `${headHeight}px`; this._headElement.style.lineHeight = this._headElement.style.height; } + + private onContextMenu(e: MouseEvent) { + const actions = this._commentMenus.getCommentThreadTitleContextActions(this._contextKeyService).getActions({ shouldForwardArgs: true }).map((value) => value[1]).flat(); + if (!actions.length) { + return; + } + this._contextMenuService.showContextMenu({ + getAnchor: () => e, + getActions: () => actions, + actionRunner: new ActionRunner(), + getActionsContext: () => { + return { + commentControlHandle: this._commentThread.controllerHandle, + commentThreadHandle: this._commentThread.commentThreadHandle, + $mid: MarshalledId.CommentThread + }; + }, + }); + } } diff --git a/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts b/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts index 4769cead246fb..f81b0150bf9a1 100644 --- a/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts +++ b/src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts @@ -27,8 +27,6 @@ import { commentThreadStateBackgroundColorVar, commentThreadStateColorVar } from import { ICellRange } from 'vs/workbench/contrib/notebook/common/notebookRange'; import { FontInfo } from 'vs/editor/common/config/fontInfo'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { ActionRunner } from 'vs/base/common/actions'; -import { MarshalledId } from 'vs/base/common/marshallingIds'; export const COMMENTEDITOR_DECORATION_KEY = 'commenteditordecoration'; @@ -64,7 +62,7 @@ export class CommentThreadWidget extends collapse: () => void; }, @ICommentService private commentService: ICommentService, - @IContextMenuService private readonly contextMenuService: IContextMenuService + @IContextMenuService readonly contextMenuService: IContextMenuService ) { super(); @@ -81,7 +79,8 @@ export class CommentThreadWidget extends this._commentMenus, this._commentThread, this._contextKeyService, - this._scopedInstatiationService + this._scopedInstatiationService, + contextMenuService ); this._header.updateCommentThread(this._commentThread); @@ -147,10 +146,6 @@ export class CommentThreadWidget extends hasFocus = false; this.updateCurrentThread(hasMouse, hasFocus); }, true)); - - this._register(dom.addDisposableListener(this.container, dom.EventType.CONTEXT_MENU, e => { - return this.onContextMenu(e); - })); } updateCommentThread(commentThread: languages.CommentThread) { @@ -291,25 +286,6 @@ export class CommentThreadWidget extends this._containerDelegate.collapse(); } - private onContextMenu(e: MouseEvent) { - const actions = this._commentMenus.getCommentThreadWidgetContextActions(this._contextKeyService).getActions({ shouldForwardArgs: true }).map((value) => value[1]).flat(); - if (!actions.length) { - return; - } - this.contextMenuService.showContextMenu({ - getAnchor: () => e, - getActions: () => actions, - actionRunner: new ActionRunner(), - getActionsContext: () => { - return { - commentControlHandle: this._commentThread.controllerHandle, - commentThreadHandle: this._commentThread.commentThreadHandle, - $mid: MarshalledId.CommentThread - }; - }, - }); - } - applyTheme(theme: IColorTheme, fontInfo: FontInfo) { const content: string[] = []; diff --git a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts index a5fe56679a4bc..f1b8c1c37b8b7 100644 --- a/src/vs/workbench/services/actions/common/menusExtensionPoint.ts +++ b/src/vs/workbench/services/actions/common/menusExtensionPoint.ts @@ -161,10 +161,10 @@ const apiMenus: IAPIMenu[] = [ supportsSubmenus: false }, { - key: 'comments/commentThread/widget/context', - id: MenuId.CommentThreadWidgetContext, - description: localize('commentThread.widgetContext', "The contributed comment thread widget context menu, rendered as a right click menu on the comment thread editor widget."), - proposed: 'contribCommentWidgetContext' + key: 'comments/commentThread/title/context', + id: MenuId.CommentThreadTitleContext, + description: localize('commentThread.titleContext', "The contributed comment thread title's peek context menu, rendered as a right click menu on the comment thread's peek title."), + proposed: 'contribCommentPeekContext' }, { key: 'comments/comment/title', @@ -177,6 +177,12 @@ const apiMenus: IAPIMenu[] = [ description: localize('comment.actions', "The contributed comment context menu, rendered as buttons below the comment editor"), supportsSubmenus: false }, + { + key: 'comments/commentThread/comment/context', + id: MenuId.CommentThreadCommentContext, + description: localize('comment.commentContext', "The contributed comment context menu, rendered as a right click menu on the an individual comment in the comment thread's peek view."), + proposed: 'contribCommentPeekContext' + }, { key: 'notebook/toolbar', id: MenuId.NotebookToolbar, diff --git a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts index 8443cf2d6b179..a946ad98d7d0a 100644 --- a/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts +++ b/src/vs/workbench/services/extensions/common/extensionsApiProposals.ts @@ -9,7 +9,7 @@ export const allApiProposals = Object.freeze({ authSession: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.authSession.d.ts', badges: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.badges.d.ts', commentsResolvedState: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.commentsResolvedState.d.ts', - contribCommentWidgetContext: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentWidgetContext.d.ts', + contribCommentPeekContext: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts', contribEditSessions: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribEditSessions.d.ts', contribLabelFormatterWorkspaceTooltip: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribLabelFormatterWorkspaceTooltip.d.ts', contribMenuBarHome: 'https://raw.githubusercontent.com/microsoft/vscode/main/src/vscode-dts/vscode.proposed.contribMenuBarHome.d.ts', diff --git a/src/vscode-dts/vscode.proposed.contribCommentWidgetContext.d.ts b/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts similarity index 88% rename from src/vscode-dts/vscode.proposed.contribCommentWidgetContext.d.ts rename to src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts index 29afd8bca611a..251df53c3a69b 100644 --- a/src/vscode-dts/vscode.proposed.contribCommentWidgetContext.d.ts +++ b/src/vscode-dts/vscode.proposed.contribCommentPeekContext.d.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -// empty placeholder for comment widget context menu +// empty placeholder for comment peek context menus // https://github.com/microsoft/vscode/issues/151533 @alexr00