Skip to content

Commit c8e26d3

Browse files
authored
chat - tweak indicator for setup to more cohorts (microsoft#250724)
1 parent 5c315bf commit c8e26d3

File tree

4 files changed

+39
-22
lines changed

4 files changed

+39
-22
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ configurationRegistry.registerConfiguration({
477477
},
478478
'chat.setup.continueLaterIndicator': { // TODO@bpasero remove me eventually
479479
type: 'boolean',
480-
description: nls.localize('chat.continueLaterIndicator', "Enable continue later indicator in the status bar."),
480+
description: nls.localize('chat.continueLaterIndicator', "Enable indicator in the status bar to finish chat setup."),
481481
default: false,
482482
tags: ['onExp', 'experimental'],
483483
},

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

Lines changed: 5 additions & 6 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, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
31+
import { ContextKeyExpr } 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), accessor.get(IContextKeyService));
596+
return new ChatSetup(context, controller, instantiationService, accessor.get(ITelemetryService), accessor.get(IWorkbenchLayoutService), accessor.get(IKeybindingService), accessor.get(IChatEntitlementService) as ChatEntitlementService, accessor.get(ILogService), accessor.get(IConfigurationService), accessor.get(IViewsService), accessor.get(IProductService), accessor.get(IOpenerService), accessor.get(IContextMenuService));
597597
});
598598
}
599599

@@ -611,14 +611,13 @@ class ChatSetup {
611611
@ITelemetryService private readonly telemetryService: ITelemetryService,
612612
@ILayoutService private readonly layoutService: IWorkbenchLayoutService,
613613
@IKeybindingService private readonly keybindingService: IKeybindingService,
614-
@IChatEntitlementService private readonly chatEntitlementService: IChatEntitlementService,
614+
@IChatEntitlementService private readonly chatEntitlementService: ChatEntitlementService,
615615
@ILogService private readonly logService: ILogService,
616616
@IConfigurationService private readonly configurationService: IConfigurationService,
617617
@IViewsService private readonly viewsService: IViewsService,
618618
@IProductService private readonly productService: IProductService,
619619
@IOpenerService private readonly openerService: IOpenerService,
620620
@IContextMenuService private readonly contextMenuService: IContextMenuService,
621-
@IContextKeyService private readonly contextKeyService: IContextKeyService
622621
) { }
623622

624623
skipDialog(): void {
@@ -640,7 +639,7 @@ class ChatSetup {
640639
}
641640

642641
private async doRun(options?: { disableChatViewReveal?: boolean }): Promise<IChatSetupResult> {
643-
ChatContextKeys.Setup.later.bindTo(this.contextKeyService).set(false);
642+
this.context.update({ later: false });
644643

645644
const dialogSkipped = this.skipDialogOnce;
646645
this.skipDialogOnce = false;
@@ -678,7 +677,7 @@ class ChatSetup {
678677
this.openerService.open(URI.parse(defaultChat.signUpUrl));
679678
return this.doRun(options); // open dialog again
680679
case ChatSetupStrategy.Canceled:
681-
ChatContextKeys.Setup.later.bindTo(this.contextKeyService).set(true);
680+
this.context.update({ later: true });
682681
this.telemetryService.publicLog2<InstallChatEvent, InstallChatClassification>('commandCenter.chatInstall', { installResult: 'failedMaybeLater', installDuration: 0, signUpErrorCode: undefined });
683682
break;
684683
}

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

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { localize } from '../../../../nls.js';
1111
import { IWorkbenchContribution } from '../../../common/contributions.js';
1212
import { IStatusbarEntry, IStatusbarEntryAccessor, IStatusbarService, ShowTooltipCommand, StatusbarAlignment, StatusbarEntryKind } from '../../../services/statusbar/browser/statusbar.js';
1313
import { $, addDisposableListener, append, clearNode, EventHelper, EventType } from '../../../../base/browser/dom.js';
14-
import { ChatEntitlement, ChatEntitlementService, IChatEntitlementService, IQuotaSnapshot } from '../common/chatEntitlementService.js';
14+
import { ChatEntitlement, ChatEntitlementService, IChatEntitlementService, IQuotaSnapshot, isProUser } from '../common/chatEntitlementService.js';
1515
import { CancellationToken } from '../../../../base/common/cancellation.js';
1616
import { defaultButtonStyles, defaultCheckboxStyles } from '../../../../platform/theme/browser/defaultStyles.js';
1717
import { Checkbox } from '../../../../base/browser/ui/toggle/toggle.js';
@@ -172,14 +172,23 @@ export class ChatStatusBarEntry extends Disposable implements IWorkbenchContribu
172172
let kind: StatusbarEntryKind | undefined;
173173

174174
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';
175+
const entitlement = this.chatEntitlementService.entitlement;
176+
177+
// Finish Setup
178+
if (
179+
(
180+
this.chatEntitlementService.sentiment.later || // user skipped setup
181+
entitlement === ChatEntitlement.Available || // user is entitled
182+
isProUser(entitlement) || // user is already pro
183+
entitlement === ChatEntitlement.Free // user is already free
184+
) &&
185+
this.configurationService.getValue('chat.setup.continueLaterIndicator') === true
186+
) {
187+
const finishSetup = localize('copilotLaterStatus', "Finish Setup");
188+
189+
text = `$(copilot) ${finishSetup}`;
190+
ariaLabel = finishSetup;
191+
kind = this.chatEntitlementService.sentiment.later ? 'prominent' : undefined;
183192
}
184193
} else {
185194
const chatQuotaExceeded = this.chatEntitlementService.quotas.chat?.percentRemaining === 0;

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

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ export class ChatEntitlementService extends Disposable implements IChatEntitleme
185185
);
186186

187187
if (
188-
!productService.defaultChatAgent || // needs product config
188+
!productService.defaultChatAgent || // needs product config
189189
(
190190
// TODO@bpasero remove this condition and 'serverlessWebEnabled' once Chat web support lands
191191
isWeb &&
@@ -895,14 +895,13 @@ export class ChatEntitlementContext extends Disposable {
895895
private readonly enterpriseContextKey: IContextKey<boolean>;
896896

897897
private readonly hiddenContext: IContextKey<boolean>;
898+
private readonly laterContext: IContextKey<boolean>;
898899
private readonly installedContext: IContextKey<boolean>;
899900
private readonly disabledContext: IContextKey<boolean>;
900901

901902
private _state: IChatEntitlementContextState;
902903
private suspendedState: IChatEntitlementContextState | undefined = undefined;
903-
get state(): IChatEntitlementContextState {
904-
return this.suspendedState ?? this._state;
905-
}
904+
get state(): IChatEntitlementContextState { return this.suspendedState ?? this._state; }
906905

907906
private readonly _onDidChange = this._register(new Emitter<void>());
908907
readonly onDidChange = this._onDidChange.event;
@@ -926,6 +925,7 @@ export class ChatEntitlementContext extends Disposable {
926925
this.businessContextKey = ChatContextKeys.Entitlement.business.bindTo(contextKeyService);
927926
this.enterpriseContextKey = ChatContextKeys.Entitlement.enterprise.bindTo(contextKeyService);
928927
this.hiddenContext = ChatContextKeys.Setup.hidden.bindTo(contextKeyService);
928+
this.laterContext = ChatContextKeys.Setup.later.bindTo(contextKeyService);
929929
this.installedContext = ChatContextKeys.Setup.installed.bindTo(contextKeyService);
930930
this.disabledContext = ChatContextKeys.Setup.disabled.bindTo(contextKeyService);
931931

@@ -956,8 +956,9 @@ export class ChatEntitlementContext extends Disposable {
956956

957957
update(context: { installed: boolean; disabled: boolean }): Promise<void>;
958958
update(context: { hidden: boolean }): Promise<void>;
959+
update(context: { later: boolean }): Promise<void>;
959960
update(context: { entitlement: ChatEntitlement }): Promise<void>;
960-
update(context: { installed?: boolean; disabled?: boolean; hidden?: boolean; entitlement?: ChatEntitlement }): Promise<void> {
961+
update(context: { installed?: boolean; disabled?: boolean; hidden?: boolean; later?: boolean; entitlement?: ChatEntitlement }): Promise<void> {
961962
this.logService.trace(`[chat entitlement context] update(): ${JSON.stringify(context)}`);
962963

963964
if (typeof context.installed === 'boolean' && typeof context.disabled === 'boolean') {
@@ -973,6 +974,10 @@ export class ChatEntitlementContext extends Disposable {
973974
this._state.hidden = context.hidden;
974975
}
975976

977+
if (typeof context.later === 'boolean') {
978+
this._state.later = context.later;
979+
}
980+
976981
if (typeof context.entitlement === 'number') {
977982
this._state.entitlement = context.entitlement;
978983

@@ -983,7 +988,10 @@ export class ChatEntitlementContext extends Disposable {
983988
}
984989
}
985990

986-
this.storageService.store(ChatEntitlementContext.CHAT_ENTITLEMENT_CONTEXT_STORAGE_KEY, this._state, StorageScope.PROFILE, StorageTarget.MACHINE);
991+
this.storageService.store(ChatEntitlementContext.CHAT_ENTITLEMENT_CONTEXT_STORAGE_KEY, {
992+
...this._state,
993+
later: undefined // do not persist this across restarts for now
994+
}, StorageScope.PROFILE, StorageTarget.MACHINE);
987995

988996
return this.updateContext();
989997
}
@@ -1005,6 +1013,7 @@ export class ChatEntitlementContext extends Disposable {
10051013
this.businessContextKey.set(this._state.entitlement === ChatEntitlement.Business);
10061014
this.enterpriseContextKey.set(this._state.entitlement === ChatEntitlement.Enterprise);
10071015
this.hiddenContext.set(!!this._state.hidden);
1016+
this.laterContext.set(!!this._state.later);
10081017
this.installedContext.set(!!this._state.installed);
10091018
this.disabledContext.set(!!this._state.disabled);
10101019

0 commit comments

Comments
 (0)