Skip to content

Commit

Permalink
migrate comment panel to use view container
Browse files Browse the repository at this point in the history
  • Loading branch information
sbatten committed Feb 12, 2020
1 parent 614a837 commit 50bc5d7
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 59 deletions.
63 changes: 37 additions & 26 deletions src/vs/workbench/api/browser/mainThreadComments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ import * as modes from 'vs/editor/common/modes';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { Registry } from 'vs/platform/registry/common/platform';
import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers';
import { Extensions as PanelExtensions, PanelDescriptor, PanelRegistry } from 'vs/workbench/browser/panel';
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, CommentThreadChanges } from '../common/extHost.protocol';
import { COMMENTS_PANEL_ID, COMMENTS_PANEL_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer';
import { COMMENTS_VIEW_ID, COMMENTS_VIEW_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer';
import { ViewContainer, IViewContainersRegistry, Extensions as ViewExtensions, ViewContainerLocation, IViewsRegistry, IViewsService, IViewDescriptorService } from 'vs/workbench/common/views';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';


export class MainThreadCommentThread implements modes.CommentThread {
Expand Down Expand Up @@ -343,13 +344,14 @@ export class MainThreadComments extends Disposable implements MainThreadComments
private _activeCommentThread?: MainThreadCommentThread;
private readonly _activeCommentThreadDisposables = this._register(new DisposableStore());

private _openPanelListener: IDisposable | null = null;
private _openViewListener: IDisposable | null = null;


constructor(
extHostContext: IExtHostContext,
@ICommentService private readonly _commentService: ICommentService,
@IPanelService private readonly _panelService: IPanelService
@IViewsService private readonly _viewsService: IViewsService,
@IViewDescriptorService private readonly _viewDescriptorService: IViewDescriptorService
) {
super();
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostComments);
Expand All @@ -376,10 +378,10 @@ export class MainThreadComments extends Disposable implements MainThreadComments
this._commentService.registerCommentController(providerId, provider);
this._commentControllers.set(handle, provider);

const commentsPanelAlreadyConstructed = this._panelService.getPanels().some(panel => panel.id === COMMENTS_PANEL_ID);
const commentsPanelAlreadyConstructed = !!this._viewDescriptorService.getViewDescriptor(COMMENTS_VIEW_ID);
if (!commentsPanelAlreadyConstructed) {
this.registerPanel(commentsPanelAlreadyConstructed);
this.registerOpenPanelListener(commentsPanelAlreadyConstructed);
this.registerView(commentsPanelAlreadyConstructed);
this.registerViewOpenedListener(commentsPanelAlreadyConstructed);
}
this._commentService.setWorkspaceComments(String(handle), []);
}
Expand Down Expand Up @@ -444,27 +446,36 @@ export class MainThreadComments extends Disposable implements MainThreadComments
return provider.deleteCommentThread(commentThreadHandle);
}

private registerPanel(commentsPanelAlreadyConstructed: boolean) {
if (!commentsPanelAlreadyConstructed) {
Registry.as<PanelRegistry>(PanelExtensions.Panels).registerPanel(PanelDescriptor.create(
CommentsPanel,
COMMENTS_PANEL_ID,
COMMENTS_PANEL_TITLE,
'commentsPanel',
10
));
private registerView(commentsViewAlreadyRegistered: boolean) {
if (!commentsViewAlreadyRegistered) {
const VIEW_CONTAINER: ViewContainer = Registry.as<IViewContainersRegistry>(ViewExtensions.ViewContainersRegistry).registerViewContainer({
id: COMMENTS_VIEW_ID,
name: COMMENTS_VIEW_TITLE,
ctorDescriptor: new SyncDescriptor(ViewPaneContainer, [COMMENTS_VIEW_ID, COMMENTS_VIEW_TITLE, { mergeViewWithContainerWhenSingleView: true, donotShowContainerTitleWhenMergedWithContainer: true }]),
order: 10,
}, ViewContainerLocation.Panel);

Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry).registerViews([{
id: COMMENTS_VIEW_ID,
name: COMMENTS_VIEW_TITLE,
canToggleVisibility: false,
ctorDescriptor: new SyncDescriptor(CommentsPanel),
focusCommand: {
id: 'workbench.action.focusCommentsPanel'
}
}], VIEW_CONTAINER);
}
}

/**
* If the comments panel has never been opened, the constructor for it has not yet run so it has
* no listeners for comment threads being set or updated. Listen for the panel opening for the
* If the comments view has never been opened, the constructor for it has not yet run so it has
* no listeners for comment threads being set or updated. Listen for the view opening for the
* first time and send it comments then.
*/
private registerOpenPanelListener(commentsPanelAlreadyConstructed: boolean) {
if (!commentsPanelAlreadyConstructed && !this._openPanelListener) {
this._openPanelListener = this._panelService.onDidPanelOpen(e => {
if (e.panel.getId() === COMMENTS_PANEL_ID) {
private registerViewOpenedListener(commentsPanelAlreadyConstructed: boolean) {
if (!commentsPanelAlreadyConstructed && !this._openViewListener) {
this._openViewListener = this._viewsService.onDidChangeViewVisibility(e => {
if (e.id === COMMENTS_VIEW_ID && e.visible) {
keys(this._commentControllers).forEach(handle => {
let threads = this._commentControllers.get(handle)!.getAllComments();

Expand All @@ -474,9 +485,9 @@ export class MainThreadComments extends Disposable implements MainThreadComments
}
});

if (this._openPanelListener) {
this._openPanelListener.dispose();
this._openPanelListener = null;
if (this._openViewListener) {
this._openViewListener.dispose();
this._openViewListener = null;
}
}
});
Expand Down
67 changes: 37 additions & 30 deletions src/vs/workbench/contrib/comments/browser/commentsPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,25 @@ import { CollapseAllAction } from 'vs/base/browser/ui/tree/treeDefaults';
import { isCodeEditor } from 'vs/editor/browser/editorBrowser';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { TreeResourceNavigator } from 'vs/platform/list/browser/listService';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { Panel } from 'vs/workbench/browser/panel';
import { CommentNode, CommentsModel, ResourceWithCommentThreads, ICommentThreadChangedEvent } from 'vs/workbench/contrib/comments/common/commentModel';
import { CommentController } from 'vs/workbench/contrib/comments/browser/commentsEditorContribution';
import { ICommentService, IWorkspaceCommentThreadsEvent } from 'vs/workbench/contrib/comments/browser/commentService';
import { IWorkspaceCommentThreadsEvent, ICommentService } from 'vs/workbench/contrib/comments/browser/commentService';
import { IEditorService, ACTIVE_GROUP, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { textLinkForeground, textLinkActiveForeground, focusBorder, textPreformatForeground } from 'vs/platform/theme/common/colorRegistry';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { ResourceLabels } from 'vs/workbench/browser/labels';
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
import { CommentsList, COMMENTS_PANEL_ID, COMMENTS_PANEL_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer';
import { CommentsList, COMMENTS_VIEW_ID, COMMENTS_VIEW_TITLE } from 'vs/workbench/contrib/comments/browser/commentsTreeViewer';
import { ViewPane, IViewPaneOptions } from 'vs/workbench/browser/parts/views/viewPaneContainer';
import { IViewDescriptorService, IViewsService } from 'vs/workbench/common/views';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
import { IOpenerService } from 'vs/platform/opener/common/opener';


export class CommentsPanel extends Panel {
export class CommentsPanel extends ViewPane {
private treeLabels!: ResourceLabels;
private tree!: CommentsList;
private treeContainer!: HTMLElement;
Expand All @@ -35,43 +38,50 @@ export class CommentsPanel extends Panel {
private commentsModel!: CommentsModel;
private collapseAllAction?: IAction;

readonly onDidChangeVisibility = this.onDidChangeBodyVisibility;

constructor(
@IInstantiationService private readonly instantiationService: IInstantiationService,
@ICommentService private readonly commentService: ICommentService,
options: IViewPaneOptions,
@IInstantiationService readonly instantiationService: IInstantiationService,
@IViewDescriptorService viewDescriptorService: IViewDescriptorService,
@IEditorService private readonly editorService: IEditorService,
@ITelemetryService telemetryService: ITelemetryService,
@IConfigurationService configurationService: IConfigurationService,
@IContextKeyService contextKeyService: IContextKeyService,
@IContextMenuService contextMenuService: IContextMenuService,
@IKeybindingService keybindingService: IKeybindingService,
@IOpenerService openerService: IOpenerService,
@IThemeService themeService: IThemeService,
@IStorageService storageService: IStorageService
@ICommentService private readonly commentService: ICommentService
) {
super(COMMENTS_PANEL_ID, telemetryService, themeService, storageService);
super({ ...(options as IViewPaneOptions), id: COMMENTS_VIEW_ID, ariaHeaderLabel: COMMENTS_VIEW_TITLE }, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService);
}

public create(parent: HTMLElement): void {
super.create(parent);
public renderBody(container: HTMLElement): void {
super.renderBody(container);

dom.addClass(parent, 'comments-panel');
dom.addClass(container, 'comments-panel');

let container = dom.append(parent, dom.$('.comments-panel-container'));
this.treeContainer = dom.append(container, dom.$('.tree-container'));
let domContainer = dom.append(container, dom.$('.comments-panel-container'));
this.treeContainer = dom.append(domContainer, dom.$('.tree-container'));
this.commentsModel = new CommentsModel();

this.createTree();
this.createMessageBox(container);
this.createMessageBox(domContainer);

this._register(this.commentService.onDidSetAllCommentThreads(this.onAllCommentsChanged, this));
this._register(this.commentService.onDidUpdateCommentThreads(this.onCommentsUpdated, this));

const styleElement = dom.createStyleSheet(parent);
const styleElement = dom.createStyleSheet(container);
this.applyStyles(styleElement);
this._register(this.themeService.onThemeChange(_ => this.applyStyles(styleElement)));

this._register(this.onDidChangeVisibility(visible => {
this._register(this.onDidChangeBodyVisibility(visible => {
if (visible) {
this.refresh();
}
}));

this.render();
this.renderComments();
}

private applyStyles(styleElement: HTMLStyleElement) {
Expand Down Expand Up @@ -101,7 +111,7 @@ export class CommentsPanel extends Panel {
styleElement.innerHTML = content.join('\n');
}

private async render(): Promise<void> {
private async renderComments(): Promise<void> {
dom.toggleClass(this.treeContainer, 'hidden', !this.commentsModel.hasCommentThreads());
await this.tree.setInput(this.commentsModel);
this.renderMessage();
Expand All @@ -116,12 +126,12 @@ export class CommentsPanel extends Panel {
return [this.collapseAllAction];
}

public layout(dimensions: dom.Dimension): void {
this.tree.layout(dimensions.height, dimensions.width);
public layoutBody(height: number, width: number): void {
this.tree.layout(height, width);
}

public getTitle(): string {
return COMMENTS_PANEL_TITLE;
return COMMENTS_VIEW_TITLE;
}

private createMessageBox(parent: HTMLElement): void {
Expand Down Expand Up @@ -224,10 +234,7 @@ export class CommentsPanel extends Panel {
CommandsRegistry.registerCommand({
id: 'workbench.action.focusCommentsPanel',
handler: async (accessor) => {
const panelService = accessor.get(IPanelService);
const panels = panelService.getPanels();
if (panels.some(panelIdentifier => panelIdentifier.id === COMMENTS_PANEL_ID)) {
await panelService.openPanel(COMMENTS_PANEL_ID, true);
}
const viewsService = accessor.get(IViewsService);
viewsService.openView(COMMENTS_VIEW_ID, true);
}
});
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { PANEL_BACKGROUND } from 'vs/workbench/common/theme';

export const COMMENTS_PANEL_ID = 'workbench.panel.comments';
export const COMMENTS_PANEL_TITLE = 'Comments';
export const COMMENTS_VIEW_ID = 'workbench.panel.comments';
export const COMMENTS_VIEW_TITLE = 'Comments';

export class CommentsAsyncDataSource implements IAsyncDataSource<any, any> {
hasChildren(element: any): boolean {
Expand Down Expand Up @@ -176,7 +176,7 @@ export class CommentsList extends WorkbenchAsyncDataTree<any, any> {
renderers,
dataSource,
{
ariaLabel: COMMENTS_PANEL_TITLE,
ariaLabel: COMMENTS_VIEW_TITLE,
keyboardSupport: true,
identityProvider: {
getId: (element: any) => {
Expand Down

0 comments on commit 50bc5d7

Please sign in to comment.