Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update comment thread context menu proposal #157800

Merged
merged 1 commit into from Aug 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/vs/platform/actions/common/actions.ts
Expand Up @@ -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');
Expand Down
8 changes: 6 additions & 2 deletions src/vs/workbench/contrib/comments/browser/commentMenus.ts
Expand Up @@ -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 {
Expand Down
42 changes: 34 additions & 8 deletions src/vs/workbench/contrib/comments/browser/commentNode.ts
Expand Up @@ -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';
Expand Down Expand Up @@ -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<T extends IRange | ICellRange> extends Disposable {
private _domNode: HTMLElement;
Expand All @@ -62,6 +63,7 @@ export class CommentNode<T extends IRange | ICellRange> extends Disposable {
private _timestampWidget: TimestampWidget | undefined;
private _contextKeyService: IContextKeyService;
private _commentContextValue: IContextKey<string>;
private _commentMenus: CommentMenus;

protected actionRunner?: IActionRunner;
protected toolbar: ToolBar | undefined;
Expand Down Expand Up @@ -97,6 +99,7 @@ export class CommentNode<T extends IRange | ICellRange> 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'));
Expand All @@ -121,6 +124,10 @@ export class CommentNode<T extends IRange | ICellRange> 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) {
Expand Down Expand Up @@ -190,6 +197,14 @@ export class CommentNode<T extends IRange | ICellRange> 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 => {
Expand All @@ -211,11 +226,7 @@ export class CommentNode<T extends IRange | ICellRange> 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);
Expand All @@ -231,8 +242,7 @@ export class CommentNode<T extends IRange | ICellRange> 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);
Expand Down Expand Up @@ -562,6 +572,22 @@ export class CommentNode<T extends IRange | ICellRange> 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) {
Expand Down
30 changes: 28 additions & 2 deletions src/vs/workbench/contrib/comments/browser/commentThreadHeader.ts
Expand Up @@ -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';
Expand All @@ -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);
Expand All @@ -36,7 +38,8 @@ export class CommentThreadHeader<T = IRange> extends Disposable {
private _commentMenus: CommentMenus,
private _commentThread: languages.CommentThread<T>,
private _contextKeyService: IContextKeyService,
private instantiationService: IInstantiationService
private instantiationService: IInstantiationService,
private _contextMenuService: IContextMenuService
) {
super();
this._headElement = <HTMLDivElement>dom.$('.head');
Expand Down Expand Up @@ -67,6 +70,10 @@ export class CommentThreadHeader<T = IRange> 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;
}

Expand Down Expand Up @@ -103,4 +110,23 @@ export class CommentThreadHeader<T = IRange> 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
};
},
});
}
}
30 changes: 3 additions & 27 deletions src/vs/workbench/contrib/comments/browser/commentThreadWidget.ts
Expand Up @@ -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';

Expand Down Expand Up @@ -64,7 +62,7 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> extends
collapse: () => void;
},
@ICommentService private commentService: ICommentService,
@IContextMenuService private readonly contextMenuService: IContextMenuService
@IContextMenuService readonly contextMenuService: IContextMenuService
) {
super();

Expand All @@ -81,7 +79,8 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> extends
this._commentMenus,
this._commentThread,
this._contextKeyService,
this._scopedInstatiationService
this._scopedInstatiationService,
contextMenuService
);

this._header.updateCommentThread(this._commentThread);
Expand Down Expand Up @@ -147,10 +146,6 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> 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<T>) {
Expand Down Expand Up @@ -291,25 +286,6 @@ export class CommentThreadWidget<T extends IRange | ICellRange = IRange> 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[] = [];

Expand Down
14 changes: 10 additions & 4 deletions src/vs/workbench/services/actions/common/menusExtensionPoint.ts
Expand Up @@ -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',
Expand All @@ -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,
Expand Down
Expand Up @@ -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',
Expand Down
Expand Up @@ -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

Expand Down