Skip to content

Commit 519df4f

Browse files
authored
PLG: Guide users to continue or finish setup (microsoft/vscode-copilot#16775) (microsoft#250614)
1 parent b2c19e6 commit 519df4f

File tree

5 files changed

+36
-8
lines changed

5 files changed

+36
-8
lines changed

src/vs/workbench/contrib/chat/browser/chat.contribution.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,12 @@ configurationRegistry.registerConfiguration({
475475
default: product.quality !== 'stable' ? 'modern' : 'default',
476476
tags: ['onExp', 'experimental']
477477
},
478+
'chat.setup.continueLaterIndicator': { // TODO@bpasero remove me eventually
479+
type: 'boolean',
480+
description: nls.localize('chat.continueLaterIndicator', "Enable continue later indicator in the status bar."),
481+
default: false,
482+
tags: ['onExp', 'experimental'],
483+
},
478484
}
479485
});
480486
Registry.as<IEditorPaneRegistry>(EditorExtensions.EditorPane).registerEditorPane(

src/vs/workbench/contrib/chat/browser/chatSetup.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import { Action2, MenuId, MenuRegistry, registerAction2 } from '../../../../plat
2828
import { ICommandService } from '../../../../platform/commands/common/commands.js';
2929
import { ConfigurationTarget, IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
3030
import { Extensions as ConfigurationExtensions, IConfigurationRegistry } from '../../../../platform/configuration/common/configurationRegistry.js';
31-
import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextkey.js';
31+
import { ContextKeyExpr, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
3232
import { createWorkbenchDialogOptions } from '../../../../platform/dialogs/browser/dialog.js';
3333
import { IDialogService } from '../../../../platform/dialogs/common/dialogs.js';
3434
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
@@ -593,7 +593,7 @@ class ChatSetup {
593593
let instance = ChatSetup.instance;
594594
if (!instance) {
595595
instance = ChatSetup.instance = instantiationService.invokeFunction(accessor => {
596-
return new ChatSetup(context, controller, instantiationService, accessor.get(ITelemetryService), accessor.get(IWorkbenchLayoutService), accessor.get(IKeybindingService), accessor.get(IChatEntitlementService), accessor.get(ILogService), accessor.get(IConfigurationService), accessor.get(IViewsService), accessor.get(IProductService), accessor.get(IOpenerService), accessor.get(IContextMenuService));
596+
return new ChatSetup(context, controller, instantiationService, accessor.get(ITelemetryService), accessor.get(IWorkbenchLayoutService), accessor.get(IKeybindingService), accessor.get(IChatEntitlementService), accessor.get(ILogService), accessor.get(IConfigurationService), accessor.get(IViewsService), accessor.get(IProductService), accessor.get(IOpenerService), accessor.get(IContextMenuService), accessor.get(IContextKeyService));
597597
});
598598
}
599599

@@ -617,7 +617,8 @@ class ChatSetup {
617617
@IViewsService private readonly viewsService: IViewsService,
618618
@IProductService private readonly productService: IProductService,
619619
@IOpenerService private readonly openerService: IOpenerService,
620-
@IContextMenuService private readonly contextMenuService: IContextMenuService
620+
@IContextMenuService private readonly contextMenuService: IContextMenuService,
621+
@IContextKeyService private readonly contextKeyService: IContextKeyService
621622
) { }
622623

623624
skipDialog(): void {
@@ -639,6 +640,8 @@ class ChatSetup {
639640
}
640641

641642
private async doRun(options?: { disableChatViewReveal?: boolean }): Promise<IChatSetupResult> {
643+
ChatContextKeys.Setup.later.bindTo(this.contextKeyService).set(false);
644+
642645
const dialogSkipped = this.skipDialogOnce;
643646
this.skipDialogOnce = false;
644647

@@ -675,6 +678,7 @@ class ChatSetup {
675678
this.openerService.open(URI.parse(defaultChat.signUpUrl));
676679
return this.doRun(options); // open dialog again
677680
case ChatSetupStrategy.Canceled:
681+
ChatContextKeys.Setup.later.bindTo(this.contextKeyService).set(true);
678682
this.telemetryService.publicLog2<InstallChatEvent, InstallChatClassification>('commandCenter.chatInstall', { installResult: 'failedMaybeLater', installDuration: 0, signUpErrorCode: undefined });
679683
break;
680684
}

src/vs/workbench/contrib/chat/browser/chatStatus.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,17 @@ export class ChatStatusBarEntry extends Disposable implements IWorkbenchContribu
171171
let ariaLabel = localize('chatStatus', "Copilot Status");
172172
let kind: StatusbarEntryKind | undefined;
173173

174-
if (!isNewUser(this.chatEntitlementService)) {
174+
if (isNewUser(this.chatEntitlementService)) {
175+
176+
// Later
177+
if (this.chatEntitlementService.sentiment.later && this.configurationService.getValue('chat.setup.continueLaterIndicator') === true) {
178+
const continueSetup = localize('copilotLaterStatus', "Continue Setup");
179+
180+
text = `$(copilot) ${continueSetup}`;
181+
ariaLabel = continueSetup;
182+
kind = 'prominent';
183+
}
184+
} else {
175185
const chatQuotaExceeded = this.chatEntitlementService.quotas.chat?.percentRemaining === 0;
176186
const completionsQuotaExceeded = this.chatEntitlementService.quotas.completions?.percentRemaining === 0;
177187

@@ -209,7 +219,7 @@ export class ChatStatusBarEntry extends Disposable implements IWorkbenchContribu
209219
// Completions Disabled
210220
else if (this.editorService.activeTextEditorLanguageId && !isCompletionsEnabled(this.configurationService, this.editorService.activeTextEditorLanguageId)) {
211221
text = `$(copilot-unavailable)`;
212-
ariaLabel = localize('completionsDisabledStatus', "Code completions Disabled");
222+
ariaLabel = localize('completionsDisabledStatus', "Code completions disabled");
213223
}
214224
}
215225

src/vs/workbench/contrib/chat/common/chatContextKeys.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@ export namespace ChatContextKeys {
5454
export const Setup = {
5555
hidden: new RawContextKey<boolean>('chatSetupHidden', false, true), // True when chat setup is explicitly hidden.
5656
installed: new RawContextKey<boolean>('chatSetupInstalled', false, true), // True when the chat extension is installed and enabled.
57-
disabled: new RawContextKey<boolean>('chatSetupDisabled', false, true) // True when the chat extension is disabled.
57+
disabled: new RawContextKey<boolean>('chatSetupDisabled', false, true), // True when the chat extension is disabled.
58+
later: new RawContextKey<boolean>('chatSetupLater', false, true) // True when the user wants to finish setup later.
5859
};
5960

6061
export const Entitlement = {

src/vs/workbench/contrib/chat/common/chatEntitlementService.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,11 @@ export interface IChatSentiment {
7878
* Chat but but disable its functionality.
7979
*/
8080
disabled?: boolean;
81+
82+
/**
83+
* User signals intent to use Chat later.
84+
*/
85+
later?: boolean;
8186
}
8287

8388
export interface IChatEntitlementService {
@@ -173,7 +178,8 @@ export class ChatEntitlementService extends Disposable implements IChatEntitleme
173178
this.contextKeyService.onDidChangeContext, e => e.affectsSome(new Set([
174179
ChatContextKeys.Setup.hidden.key,
175180
ChatContextKeys.Setup.disabled.key,
176-
ChatContextKeys.Setup.installed.key
181+
ChatContextKeys.Setup.installed.key,
182+
ChatContextKeys.Setup.later.key
177183
])), this._store
178184
), () => { }, this._store
179185
);
@@ -306,7 +312,8 @@ export class ChatEntitlementService extends Disposable implements IChatEntitleme
306312
return {
307313
installed: this.contextKeyService.getContextKeyValue<boolean>(ChatContextKeys.Setup.installed.key) === true,
308314
hidden: this.contextKeyService.getContextKeyValue<boolean>(ChatContextKeys.Setup.hidden.key) === true,
309-
disabled: this.contextKeyService.getContextKeyValue<boolean>(ChatContextKeys.Setup.disabled.key) === true
315+
disabled: this.contextKeyService.getContextKeyValue<boolean>(ChatContextKeys.Setup.disabled.key) === true,
316+
later: this.contextKeyService.getContextKeyValue<boolean>(ChatContextKeys.Setup.later.key) === true
310317
};
311318
}
312319

0 commit comments

Comments
 (0)