提交 f13c7359 编写于 作者: S Sandeep Somavarapu

Fix #104064

上级 1b60d5b2
......@@ -21,8 +21,13 @@ export class ConfigBasedRecommendations extends ExtensionRecommendations {
private importantTips: IConfigBasedExtensionTip[] = [];
private otherTips: IConfigBasedExtensionTip[] = [];
private _recommendations: ExtensionRecommendation[] = [];
get recommendations(): ReadonlyArray<ExtensionRecommendation> { return this._recommendations; }
private _otherRecommendations: ExtensionRecommendation[] = [];
get otherRecommendations(): ReadonlyArray<ExtensionRecommendation> { return this._otherRecommendations; }
private _importantRecommendations: ExtensionRecommendation[] = [];
get importantRecommendations(): ReadonlyArray<ExtensionRecommendation> { return this._importantRecommendations; }
get recommendations(): ReadonlyArray<ExtensionRecommendation> { return [...this.importantRecommendations, ...this.otherRecommendations]; }
constructor(
isExtensionAllowedToBeRecommended: (extensionId: string) => boolean,
......@@ -61,7 +66,8 @@ export class ConfigBasedRecommendations extends ExtensionRecommendations {
}
this.importantTips = [...importantTips.values()];
this.otherTips = [...otherTips.values()].filter(tip => !importantTips.has(tip.extensionId));
this._recommendations = [...this.importantTips, ...this.otherTips].map(tip => this.toExtensionRecommendation(tip));
this._otherRecommendations = this.otherTips.map(tip => this.toExtensionRecommendation(tip));
this._importantRecommendations = this.importantTips.map(tip => this.toExtensionRecommendation(tip));
}
private async promptWorkspaceRecommendations(): Promise<void> {
......
......@@ -25,8 +25,14 @@ type ExeExtensionRecommendationsClassification = {
export class ExeBasedRecommendations extends ExtensionRecommendations {
readonly _recommendations: ExtensionRecommendation[] = [];
get recommendations(): ReadonlyArray<ExtensionRecommendation> { return this._recommendations; }
private readonly _otherRecommendations: ExtensionRecommendation[] = [];
get otherRecommendations(): ReadonlyArray<ExtensionRecommendation> { return this._otherRecommendations; }
private readonly _importantRecommendations: ExtensionRecommendation[] = [];
get importantRecommendations(): ReadonlyArray<ExtensionRecommendation> { return this._importantRecommendations; }
get recommendations(): ReadonlyArray<ExtensionRecommendation> { return [...this.importantRecommendations, ...this.otherRecommendations]; }
private readonly tasExperimentService: ITASExperimentService | undefined;
......@@ -54,16 +60,30 @@ export class ExeBasedRecommendations extends ExtensionRecommendations {
protected async doActivate(): Promise<void> {
const otherExectuableBasedTips = await this.extensionTipsService.getOtherExecutableBasedTips();
otherExectuableBasedTips.forEach(tip => this._recommendations.push(this.toExtensionRecommendation(tip)));
otherExectuableBasedTips.forEach(tip => this._otherRecommendations.push(this.toExtensionRecommendation(tip)));
await this.fetchImportantExeBasedRecommendations();
}
private async fetchAndPromptImportantExeBasedRecommendations(): Promise<void> {
private _importantExeBasedRecommendations: Promise<IStringDictionary<IExecutableBasedExtensionTip>> | undefined;
private async fetchImportantExeBasedRecommendations(): Promise<IStringDictionary<IExecutableBasedExtensionTip>> {
if (!this._importantExeBasedRecommendations) {
this._importantExeBasedRecommendations = this.doFetchImportantExeBasedRecommendations();
}
return this._importantExeBasedRecommendations;
}
private async doFetchImportantExeBasedRecommendations(): Promise<IStringDictionary<IExecutableBasedExtensionTip>> {
const importantExeBasedRecommendations: IStringDictionary<IExecutableBasedExtensionTip> = {};
const importantExectuableBasedTips = await this.extensionTipsService.getImportantExecutableBasedTips();
importantExectuableBasedTips.forEach(tip => {
this._recommendations.push(this.toExtensionRecommendation(tip));
this._importantRecommendations.push(this.toExtensionRecommendation(tip));
importantExeBasedRecommendations[tip.extensionId.toLowerCase()] = tip;
});
return importantExeBasedRecommendations;
}
private async fetchAndPromptImportantExeBasedRecommendations(): Promise<void> {
const importantExeBasedRecommendations = await this.fetchImportantExeBasedRecommendations();
const local = await this.extensionManagementService.getInstalled();
const { installed, uninstalled } = this.groupByInstalled(Object.keys(importantExeBasedRecommendations), local);
......
......@@ -142,8 +142,8 @@ export class ExtensionRecommendationsService extends Disposable implements IExte
await this.activateProactiveRecommendations();
const recommendations = [
...this.configBasedRecommendations.recommendations,
...this.exeBasedRecommendations.recommendations,
...this.configBasedRecommendations.otherRecommendations,
...this.exeBasedRecommendations.otherRecommendations,
...this.dynamicWorkspaceRecommendations.recommendations,
...this.experimentalRecommendations.recommendations
];
......@@ -159,6 +159,26 @@ export class ExtensionRecommendationsService extends Disposable implements IExte
});
}
async getImportantRecommendations(): Promise<IExtensionRecommendation[]> {
await this.activateProactiveRecommendations();
const recommendations = [
...this.fileBasedRecommendations.importantRecommendations,
...this.configBasedRecommendations.importantRecommendations,
...this.exeBasedRecommendations.importantRecommendations,
];
const extensionIds = distinct(recommendations.map(e => e.extensionId))
.filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId));
shuffle(extensionIds, this.sessionSeed);
return extensionIds.map(extensionId => {
const sources: ExtensionRecommendationSource[] = distinct(recommendations.filter(r => r.extensionId === extensionId).map(r => r.source));
return (<IExtensionRecommendation>{ extensionId, sources });
});
}
getKeymapRecommendations(): IExtensionRecommendation[] {
return this.toExtensionRecommendations(this.keymapRecommendations.recommendations);
}
......
......@@ -551,10 +551,11 @@ export class ExtensionsListView extends ViewPane {
const configBasedRecommendationsPromise = this.tipsService.getConfigBasedRecommendations();
const othersPromise = this.tipsService.getOtherRecommendations();
const workspacePromise = this.tipsService.getWorkspaceRecommendations();
const importantRecommendationsPromise = this.tipsService.getImportantRecommendations();
return Promise.all([othersPromise, workspacePromise, configBasedRecommendationsPromise])
.then(([others, workspaceRecommendations, configBasedRecommendations]) => {
const names = this.getTrimmedRecommendations(local, value, fileBasedRecommendations, configBasedRecommendations, others, workspaceRecommendations);
return Promise.all([othersPromise, workspacePromise, configBasedRecommendationsPromise, importantRecommendationsPromise])
.then(([others, workspaceRecommendations, configBasedRecommendations, importantRecommendations]) => {
const names = this.getTrimmedRecommendations(local, value, importantRecommendations, fileBasedRecommendations, configBasedRecommendations, others, workspaceRecommendations);
const recommendationsWithReason = this.tipsService.getAllRecommendationsWithReason();
/* __GDPR__
"extensionAllRecommendations:open" : {
......@@ -607,14 +608,15 @@ export class ExtensionsListView extends ViewPane {
const configBasedRecommendationsPromise = this.tipsService.getConfigBasedRecommendations();
const othersPromise = this.tipsService.getOtherRecommendations();
const workspacePromise = this.tipsService.getWorkspaceRecommendations();
const importantRecommendationsPromise = this.tipsService.getImportantRecommendations();
return Promise.all([othersPromise, workspacePromise, configBasedRecommendationsPromise])
.then(([others, workspaceRecommendations, configBasedRecommendations]) => {
return Promise.all([othersPromise, workspacePromise, configBasedRecommendationsPromise, importantRecommendationsPromise])
.then(([others, workspaceRecommendations, configBasedRecommendations, importantRecommendations]) => {
configBasedRecommendations = configBasedRecommendations.filter(x => workspaceRecommendations.every(({ extensionId }) => x.extensionId !== extensionId));
fileBasedRecommendations = fileBasedRecommendations.filter(x => workspaceRecommendations.every(({ extensionId }) => x.extensionId !== extensionId));
others = others.filter(x => workspaceRecommendations.every(({ extensionId }) => x.extensionId !== extensionId));
const names = this.getTrimmedRecommendations(local, value, fileBasedRecommendations, configBasedRecommendations, others, []);
const names = this.getTrimmedRecommendations(local, value, importantRecommendations, fileBasedRecommendations, configBasedRecommendations, others, []);
const recommendationsWithReason = this.tipsService.getAllRecommendationsWithReason();
/* __GDPR__
......@@ -647,22 +649,30 @@ export class ExtensionsListView extends ViewPane {
}
// Given all recommendations, trims and returns recommendations in the relevant order after filtering out installed extensions
private getTrimmedRecommendations(installedExtensions: IExtension[], value: string, fileBasedRecommendations: IExtensionRecommendation[], configBasedRecommendations: IExtensionRecommendation[], otherRecommendations: IExtensionRecommendation[], workspaceRecommendations: IExtensionRecommendation[]): string[] {
private getTrimmedRecommendations(installedExtensions: IExtension[], value: string, importantRecommendations: IExtensionRecommendation[], fileBasedRecommendations: IExtensionRecommendation[], configBasedRecommendations: IExtensionRecommendation[], otherRecommendations: IExtensionRecommendation[], workspaceRecommendations: IExtensionRecommendation[]): string[] {
const totalCount = 10;
workspaceRecommendations = workspaceRecommendations
.filter(recommendation => {
return !this.isRecommendationInstalled(recommendation, installedExtensions)
&& recommendation.extensionId.toLowerCase().indexOf(value) > -1;
});
importantRecommendations = importantRecommendations
.filter(recommendation => {
return !this.isRecommendationInstalled(recommendation, installedExtensions)
&& workspaceRecommendations.every(workspaceRecommendation => workspaceRecommendation.extensionId !== recommendation.extensionId)
&& recommendation.extensionId.toLowerCase().indexOf(value) > -1;
});
configBasedRecommendations = configBasedRecommendations
.filter(recommendation => {
return !this.isRecommendationInstalled(recommendation, installedExtensions)
&& workspaceRecommendations.every(workspaceRecommendation => workspaceRecommendation.extensionId !== recommendation.extensionId)
&& importantRecommendations.every(importantRecommendation => importantRecommendation.extensionId !== recommendation.extensionId)
&& recommendation.extensionId.toLowerCase().indexOf(value) > -1;
});
fileBasedRecommendations = fileBasedRecommendations.filter(recommendation => {
return !this.isRecommendationInstalled(recommendation, installedExtensions)
&& workspaceRecommendations.every(workspaceRecommendation => workspaceRecommendation.extensionId !== recommendation.extensionId)
&& importantRecommendations.every(importantRecommendation => importantRecommendation.extensionId !== recommendation.extensionId)
&& configBasedRecommendations.every(configBasedRecommendation => configBasedRecommendation.extensionId !== recommendation.extensionId)
&& recommendation.extensionId.toLowerCase().indexOf(value) > -1;
});
......@@ -670,13 +680,14 @@ export class ExtensionsListView extends ViewPane {
return !this.isRecommendationInstalled(recommendation, installedExtensions)
&& fileBasedRecommendations.every(fileBasedRecommendation => fileBasedRecommendation.extensionId !== recommendation.extensionId)
&& workspaceRecommendations.every(workspaceRecommendation => workspaceRecommendation.extensionId !== recommendation.extensionId)
&& importantRecommendations.every(importantRecommendation => importantRecommendation.extensionId !== recommendation.extensionId)
&& configBasedRecommendations.every(configBasedRecommendation => configBasedRecommendation.extensionId !== recommendation.extensionId)
&& recommendation.extensionId.toLowerCase().indexOf(value) > -1;
});
const otherCount = Math.min(2, otherRecommendations.length);
const fileBasedCount = Math.min(fileBasedRecommendations.length, totalCount - workspaceRecommendations.length - configBasedRecommendations.length - otherCount);
const recommendations = [...workspaceRecommendations, ...configBasedRecommendations];
const fileBasedCount = Math.min(fileBasedRecommendations.length, totalCount - workspaceRecommendations.length - importantRecommendations.length - configBasedRecommendations.length - otherCount);
const recommendations = [...workspaceRecommendations, ...importantRecommendations, ...configBasedRecommendations];
recommendations.push(...fileBasedRecommendations.splice(0, fileBasedCount));
recommendations.push(...otherRecommendations.splice(0, otherCount));
......
......@@ -75,6 +75,14 @@ export class FileBasedRecommendations extends ExtensionRecommendations {
return recommendations;
}
get importantRecommendations(): ReadonlyArray<ExtensionRecommendation> {
return this.recommendations.filter(e => this.importantExtensionTips[e.extensionId]);
}
get otherRecommendations(): ReadonlyArray<ExtensionRecommendation> {
return this.recommendations.filter(e => !this.importantExtensionTips[e.extensionId]);
}
constructor(
isExtensionAllowedToBeRecommended: (extensionId: string) => boolean,
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
......
......@@ -128,6 +128,7 @@ export interface IExtensionRecommendationsService {
getAllRecommendationsWithReason(): IStringDictionary<IExtensionRecommendationReson>;
getFileBasedRecommendations(): IExtensionRecommendation[];
getImportantRecommendations(): Promise<IExtensionRecommendation[]>;
getConfigBasedRecommendations(): Promise<IExtensionRecommendation[]>;
getOtherRecommendations(): Promise<IExtensionRecommendation[]>;
getWorkspaceRecommendations(): Promise<IExtensionRecommendation[]>;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册