diff --git a/src/vs/workbench/api/browser/mainThreadComments.ts b/src/vs/workbench/api/browser/mainThreadComments.ts index bbe5edd3b6b..3a3afc745fd 100644 --- a/src/vs/workbench/api/browser/mainThreadComments.ts +++ b/src/vs/workbench/api/browser/mainThreadComments.ts @@ -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 { @@ -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); @@ -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), []); } @@ -444,27 +446,36 @@ export class MainThreadComments extends Disposable implements MainThreadComments return provider.deleteCommentThread(commentThreadHandle); } - private registerPanel(commentsPanelAlreadyConstructed: boolean) { - if (!commentsPanelAlreadyConstructed) { - Registry.as(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(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(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(); @@ -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; } } }); diff --git a/src/vs/workbench/contrib/comments/browser/commentsPanel.ts b/src/vs/workbench/contrib/comments/browser/commentsPanel.ts index 923fb4dcd0b..ebd2b1ae5de 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsPanel.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsPanel.ts @@ -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; @@ -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) { @@ -101,7 +111,7 @@ export class CommentsPanel extends Panel { styleElement.innerHTML = content.join('\n'); } - private async render(): Promise { + private async renderComments(): Promise { dom.toggleClass(this.treeContainer, 'hidden', !this.commentsModel.hasCommentThreads()); await this.tree.setInput(this.commentsModel); this.renderMessage(); @@ -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 { @@ -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); } }); diff --git a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts index ba8510c41f4..f047707083b 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsTreeViewer.ts @@ -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 { hasChildren(element: any): boolean { @@ -176,7 +176,7 @@ export class CommentsList extends WorkbenchAsyncDataTree { renderers, dataSource, { - ariaLabel: COMMENTS_PANEL_TITLE, + ariaLabel: COMMENTS_VIEW_TITLE, keyboardSupport: true, identityProvider: { getId: (element: any) => {