diff --git a/src/vs/workbench/api/electron-browser/mainThreadComments.ts b/src/vs/workbench/api/electron-browser/mainThreadComments.ts index 226f8e2367ed9dd7880ee09b4cb7012233bcd0f8..a0bfc4493413924a7930d22aee4df7ef05d9b866 100644 --- a/src/vs/workbench/api/electron-browser/mainThreadComments.ts +++ b/src/vs/workbench/api/electron-browser/mainThreadComments.ts @@ -17,6 +17,8 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { URI } from 'vs/base/common/uri'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { generateUuid } from 'vs/base/common/uuid'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ICommentsConfiguration } from 'vs/workbench/parts/comments/electron-browser/comments.contribution'; export class MainThreadDocumentCommentProvider implements modes.DocumentCommentProvider { private _proxy: ExtHostCommentsShape; @@ -72,18 +74,18 @@ export class MainThreadComments extends Disposable implements MainThreadComments private _documentProviders = new Map(); private _workspaceProviders = new Map(); private _handlers = new Map(); - private _firstSessionStart: boolean; + private _openPanelListener: IDisposable | null; constructor( extHostContext: IExtHostContext, @IEditorService private _editorService: IEditorService, @ICommentService private _commentService: ICommentService, @IPanelService private _panelService: IPanelService, - @ITelemetryService private _telemetryService: ITelemetryService + @ITelemetryService private _telemetryService: ITelemetryService, + @IConfigurationService private _configurationService: IConfigurationService ) { super(); this._disposables = []; - this._firstSessionStart = true; this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostComments); } @@ -97,19 +99,62 @@ export class MainThreadComments extends Disposable implements MainThreadComments this._commentService.registerDataProvider(providerId, handler); } + /** + * 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 + * 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) { + keys(this._workspaceProviders).forEach(handle => { + this._proxy.$provideWorkspaceComments(handle).then(commentThreads => { + if (commentThreads) { + const providerId = this._handlers.get(handle); + this._commentService.setWorkspaceComments(providerId, commentThreads); + } + + }); + }); + + this._openPanelListener.dispose(); + this._openPanelListener = null; + } + }); + } + } + $registerWorkspaceCommentProvider(handle: number, extensionId: string): void { this._workspaceProviders.set(handle, undefined); const providerId = generateUuid(); this._handlers.set(handle, providerId); + const commentsPanelAlreadyConstructed = this._panelService.getPanels().some(panel => panel.id === COMMENTS_PANEL_ID); this._panelService.setPanelEnablement(COMMENTS_PANEL_ID, true); - if (this._firstSessionStart) { + + const openPanel = this._configurationService.getValue('comments').openPanel; + + + if (openPanel === 'neverOpen') { + this.registerOpenPanelListener(commentsPanelAlreadyConstructed); + } + + if (openPanel === 'openOnSessionStart') { this._panelService.openPanel(COMMENTS_PANEL_ID); - this._firstSessionStart = false; } + this._proxy.$provideWorkspaceComments(handle).then(commentThreads => { if (commentThreads) { + if (openPanel === 'openOnSessionStartWithComments' && commentThreads.length) { + if (commentThreads.length) { + this._panelService.openPanel(COMMENTS_PANEL_ID); + } else { + this.registerOpenPanelListener(commentsPanelAlreadyConstructed); + } + } + this._commentService.setWorkspaceComments(providerId, commentThreads); } }); @@ -135,7 +180,13 @@ export class MainThreadComments extends Disposable implements MainThreadComments this._workspaceProviders.delete(handle); if (this._workspaceProviders.size === 0) { this._panelService.setPanelEnablement(COMMENTS_PANEL_ID, false); + + if (this._openPanelListener) { + this._openPanelListener.dispose(); + this._openPanelListener = null; + } } + const handlerId = this._handlers.get(handle); this._commentService.removeWorkspaceComments(handlerId); this._handlers.delete(handle); diff --git a/src/vs/workbench/parts/comments/electron-browser/comments.contribution.ts b/src/vs/workbench/parts/comments/electron-browser/comments.contribution.ts index 9698f7ec05ce12c50d44d156f73611cc84c1ae75..0fa4480285884909a6609659d534f85ad61e04bd 100644 --- a/src/vs/workbench/parts/comments/electron-browser/comments.contribution.ts +++ b/src/vs/workbench/parts/comments/electron-browser/comments.contribution.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as nls from 'vs/nls'; import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { Registry } from 'vs/platform/registry/common/platform'; @@ -12,6 +13,11 @@ import { IPanelService } from 'vs/workbench/services/panel/common/panelService'; import { COMMENTS_PANEL_ID, COMMENTS_PANEL_TITLE, CommentsPanel } from './commentsPanel'; import 'vs/workbench/parts/comments/electron-browser/commentsEditorContribution'; import { ICommentService, CommentService } from 'vs/workbench/parts/comments/electron-browser/commentService'; +import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry'; + +export interface ICommentsConfiguration { + openPanel: 'neverOpen' | 'openOnSessionStart' | 'openOnSessionStartWithComments'; +} export class CommentPanelVisibilityUpdater implements IWorkbenchContribution { @@ -35,6 +41,21 @@ Registry.as(PanelExtensions.Panels).registerPanel(new PanelDescri 10 )); + +Registry.as(ConfigurationExtensions.Configuration).registerConfiguration({ + id: 'comments', + order: 20, + title: nls.localize('commentsConfigurationTitle', "Comments"), + type: 'object', + properties: { + 'comments.openPanel': { + enum: ['neverOpen', 'openOnSessionStart', 'openOnSessionStartWithComments'], + default: 'openOnSessionStartWithComments', + description: nls.localize('openComments', "Controls when the comments panel should open.") + } + } +}); + // Register view location updater Registry.as(WorkbenchExtensions.Workbench).registerWorkbenchContribution(CommentPanelVisibilityUpdater, LifecyclePhase.Starting); diff --git a/src/vs/workbench/parts/preferences/browser/settingsLayout.ts b/src/vs/workbench/parts/preferences/browser/settingsLayout.ts index 2dc95fd5a3c234613ec2594c3bb322712f0be1a2..f1032c37261a1c53f1a3fefc6b528c1146d1eff4 100644 --- a/src/vs/workbench/parts/preferences/browser/settingsLayout.ts +++ b/src/vs/workbench/parts/preferences/browser/settingsLayout.ts @@ -154,6 +154,11 @@ export const tocData: ITOCEntry = { id: 'features/problems', label: localize('problems', "Problems"), settings: ['problems.*'] + }, + { + id: 'features/comments', + label: localize('comments', "Comments"), + settings: ['comments.*'] } ] },