Skip to content

Commit feb02c6

Browse files
authored
Add survey for MPLS usage (#16403)
1 parent 41d967b commit feb02c6

6 files changed

Lines changed: 373 additions & 0 deletions

File tree

package.nls.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
"ExtensionSurveyBanner.bannerLabelYes": "Yes, take survey now",
9696
"ExtensionSurveyBanner.bannerLabelNo": "No, thanks",
9797
"ExtensionSurveyBanner.maybeLater": "Maybe later",
98+
"ExtensionSurveyBanner.mplsMessage": "Can you please take 2 minutes to tell us about your experience using the Microsoft Python Language Server?",
9899
"ExtensionChannels.installingInsidersMessage": "Installing Insiders... ",
99100
"ExtensionChannels.installingStableMessage": "Installing Stable... ",
100101
"ExtensionChannels.installationCompleteMessage": "complete.",

src/client/activation/serviceRegistry.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ import {
5959
LanguageServerType,
6060
} from './types';
6161
import { JediLanguageServerActivator } from './jedi/activator';
62+
import { IDiagnosticsService } from '../application/diagnostics/types';
63+
import {
64+
MPLSSurveyDiagnosticService,
65+
MPLSSurveyDiagnosticServiceId,
66+
} from '../application/diagnostics/checks/mplsSurvey';
6267

6368
export function registerTypes(serviceManager: IServiceManager, languageServerType: LanguageServerType): void {
6469
serviceManager.addSingleton<ILanguageServerCache>(ILanguageServerCache, LanguageServerExtensionActivationService);
@@ -109,6 +114,11 @@ export function registerTypes(serviceManager: IServiceManager, languageServerTyp
109114
DotNetLanguageServerPackageService,
110115
);
111116
registerDotNetTypes(serviceManager);
117+
serviceManager.addSingleton<IDiagnosticsService>(
118+
IDiagnosticsService,
119+
MPLSSurveyDiagnosticService,
120+
MPLSSurveyDiagnosticServiceId,
121+
);
112122
} else if (languageServerType === LanguageServerType.Node) {
113123
serviceManager.add<ILanguageServerAnalysisOptions>(
114124
ILanguageServerAnalysisOptions,
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
// eslint-disable-next-line max-classes-per-file
5+
import { inject, named } from 'inversify';
6+
import { DiagnosticSeverity, UIKind } from 'vscode';
7+
import * as querystring from 'querystring';
8+
import { IDisposableRegistry, Resource } from '../../../common/types';
9+
import { ExtensionSurveyBanner } from '../../../common/utils/localize';
10+
import { IServiceContainer } from '../../../ioc/types';
11+
import { BaseDiagnostic, BaseDiagnosticsService } from '../base';
12+
import { DiagnosticCodes } from '../constants';
13+
import { DiagnosticCommandPromptHandlerServiceId, MessageCommandPrompt } from '../promptHandler';
14+
import { DiagnosticScope, IDiagnostic, IDiagnosticHandlerService } from '../types';
15+
import { IApplicationEnvironment } from '../../../common/application/types';
16+
import { IPlatformService } from '../../../common/platform/types';
17+
import { IDiagnosticsCommandFactory } from '../commands/types';
18+
19+
export class MPLSSurveyDiagnostic extends BaseDiagnostic {
20+
constructor(message: string, resource: Resource) {
21+
super(
22+
DiagnosticCodes.MPLSSurveyDiagnostic,
23+
message,
24+
DiagnosticSeverity.Information,
25+
DiagnosticScope.Global,
26+
resource,
27+
);
28+
}
29+
}
30+
31+
export const MPLSSurveyDiagnosticServiceId = 'MPLSSurveyDiagnosticServiceId';
32+
33+
export class MPLSSurveyDiagnosticService extends BaseDiagnosticsService {
34+
constructor(
35+
@inject(IServiceContainer) serviceContainer: IServiceContainer,
36+
@inject(IDiagnosticHandlerService)
37+
@named(DiagnosticCommandPromptHandlerServiceId)
38+
protected readonly messageService: IDiagnosticHandlerService<MessageCommandPrompt>,
39+
@inject(IDisposableRegistry) disposableRegistry: IDisposableRegistry,
40+
@inject(IApplicationEnvironment) private appEnvironment: IApplicationEnvironment,
41+
@inject(IPlatformService) private platformService: IPlatformService,
42+
) {
43+
super([DiagnosticCodes.MPLSSurveyDiagnostic], serviceContainer, disposableRegistry, true);
44+
}
45+
46+
public async diagnose(resource: Resource): Promise<IDiagnostic[]> {
47+
if (this.appEnvironment.uiKind === UIKind?.Web) {
48+
return [];
49+
}
50+
51+
return [new MPLSSurveyDiagnostic(ExtensionSurveyBanner.mplsMessage(), resource)];
52+
}
53+
54+
protected async onHandle(diagnostics: IDiagnostic[]): Promise<void> {
55+
if (diagnostics.length === 0 || !this.canHandle(diagnostics[0])) {
56+
return;
57+
}
58+
59+
const diagnostic = diagnostics[0];
60+
if (await this.filterService.shouldIgnoreDiagnostic(diagnostic.code)) {
61+
return;
62+
}
63+
64+
const commandFactory = this.serviceContainer.get<IDiagnosticsCommandFactory>(IDiagnosticsCommandFactory);
65+
66+
await this.messageService.handle(diagnostic, {
67+
commandPrompts: [
68+
{
69+
prompt: ExtensionSurveyBanner.bannerLabelYes(),
70+
command: {
71+
diagnostic,
72+
invoke: () => this.launchSurvey(diagnostic),
73+
},
74+
},
75+
{
76+
prompt: ExtensionSurveyBanner.maybeLater(),
77+
},
78+
{
79+
prompt: ExtensionSurveyBanner.bannerLabelNo(),
80+
command: commandFactory.createCommand(diagnostic, {
81+
type: 'ignore',
82+
options: DiagnosticScope.Global,
83+
}),
84+
},
85+
],
86+
});
87+
}
88+
89+
private async launchSurvey(diagnostic: IDiagnostic) {
90+
const query = querystring.stringify({
91+
o: encodeURIComponent(this.platformService.osType), // platform
92+
v: encodeURIComponent(this.appEnvironment.vscodeVersion),
93+
e: encodeURIComponent(this.appEnvironment.packageJson.version), // extension version
94+
m: encodeURIComponent(this.appEnvironment.sessionId),
95+
});
96+
const url = `https://aka.ms/mpls-experience-survey?${query}`;
97+
98+
const commandFactory = this.serviceContainer.get<IDiagnosticsCommandFactory>(IDiagnosticsCommandFactory);
99+
await commandFactory.createCommand(diagnostic, { type: 'ignore', options: DiagnosticScope.Global }).invoke();
100+
await commandFactory.createCommand(diagnostic, { type: 'launch', options: url }).invoke();
101+
}
102+
}

src/client/application/diagnostics/constants.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ export enum DiagnosticCodes {
2020
ConfigPythonPathDiagnostic = 'ConfigPythonPathDiagnostic',
2121
UpgradeCodeRunnerDiagnostic = 'UpgradeCodeRunnerDiagnostic',
2222
PylanceDefaultDiagnostic = 'PylanceDefaultDiagnostic',
23+
MPLSSurveyDiagnostic = 'MPLSSurveyDiagnostic',
2324
}

src/client/common/utils/localize.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,10 @@ export namespace ExtensionSurveyBanner {
411411
export const bannerLabelYes = localize('ExtensionSurveyBanner.bannerLabelYes', 'Yes, take survey now');
412412
export const bannerLabelNo = localize('ExtensionSurveyBanner.bannerLabelNo', 'No, thanks');
413413
export const maybeLater = localize('ExtensionSurveyBanner.maybeLater', 'Maybe later');
414+
export const mplsMessage = localize(
415+
'ExtensionSurveyBanner.mplsMessage',
416+
'Can you please take 2 minutes to tell us about your experience using the Microsoft Python Language Server?',
417+
);
414418
}
415419

416420
export namespace Products {

0 commit comments

Comments
 (0)