@@ -12,11 +12,9 @@ import { IFeaturedExtension } from 'vs/base/common/product';
1212import { CancellationToken } from 'vs/base/common/cancellation' ;
1313import { IStorageService , StorageScope , StorageTarget } from 'vs/platform/storage/common/storage' ;
1414import { localize } from 'vs/nls' ;
15- import { IWorkbenchAssignmentService } from 'vs/workbench/services/assignment/common/assignmentService' ;
1615import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions' ;
17- import { raceTimeout } from 'vs/base/ common/async ' ;
16+ import { IExtensionService } from 'vs/workbench/services/extensions/ common/extensions ' ;
1817
19- type FeaturedExtensionTreatment = { extensions : string [ ] ; showAsList ?: string } ;
2018type FeaturedExtensionStorageData = { title : string ; description : string ; imagePath : string ; date : number } ;
2119
2220export const IFeaturedExtensionsService = createDecorator < IFeaturedExtensionsService > ( 'featuredExtensionsService' ) ;
@@ -38,20 +36,19 @@ export class FeaturedExtensionsService extends Disposable implements IFeaturedEx
3836 declare readonly _serviceBrand : undefined ;
3937
4038 private ignoredExtensions : Set < string > = new Set < string > ( ) ;
41- private treatment : FeaturedExtensionTreatment | undefined ;
4239 private _isInitialized : boolean = false ;
4340
4441 private static readonly STORAGE_KEY = 'workbench.welcomePage.extensionMetadata' ;
4542
4643 constructor (
4744 @IExtensionManagementService private readonly extensionManagementService : IExtensionManagementService ,
48- @IWorkbenchAssignmentService private readonly tasExperimentService : IWorkbenchAssignmentService ,
45+ @IExtensionService private readonly extensionService : IExtensionService ,
4946 @IStorageService private readonly storageService : IStorageService ,
5047 @IProductService private readonly productService : IProductService ,
5148 @IExtensionGalleryService private readonly galleryService : IExtensionGalleryService ,
5249 ) {
5350 super ( ) ;
54- this . title = localize ( 'gettingStarted.featuredTitle' , 'Featured ' ) ;
51+ this . title = localize ( 'gettingStarted.featuredTitle' , 'Recommended ' ) ;
5552 }
5653
5754 title : string ;
@@ -60,19 +57,11 @@ export class FeaturedExtensionsService extends Disposable implements IFeaturedEx
6057
6158 await this . _init ( ) ;
6259
63- let treatments = this . treatment ?. extensions ?. filter ( extension => ! this . ignoredExtensions . has ( extension ) ) ?? new Array < string > ( ) ;
64- const featuredExtensions : IFeaturedExtension [ ] = new Array ( ) ;
65-
66- if ( this . treatment ?. showAsList !== 'true' && treatments . length > 0 ) {
67- // pick a random extensionId for display
68- const treatment = treatments [ Math . floor ( Math . random ( ) * treatments . length ) ] ;
69- treatments = [ treatment ] ;
70- }
71-
72- for ( const treatment of treatments ) {
73- const extension = await this . resolveExtension ( treatment ) ;
74- if ( extension ) {
75- featuredExtensions . push ( extension ) ;
60+ const featuredExtensions : IFeaturedExtension [ ] = [ ] ;
61+ for ( const extension of this . productService . featuredExtensions ?. filter ( e => ! this . ignoredExtensions . has ( e . id ) ) ?? [ ] ) {
62+ const resolvedExtension = await this . resolveExtension ( extension ) ;
63+ if ( resolvedExtension ) {
64+ featuredExtensions . push ( resolvedExtension ) ;
7665 }
7766 }
7867
@@ -85,50 +74,42 @@ export class FeaturedExtensionsService extends Disposable implements IFeaturedEx
8574 return ;
8675 }
8776
88- const [ extensions , extensionListTitle ] = await Promise . all ( [ raceTimeout ( this . tasExperimentService ?. getTreatment < string > ( 'welcome.featured.item' ) , 2000 ) ,
89- raceTimeout ( this . tasExperimentService ?. getTreatment < string > ( 'welcome.featured.title' ) , 2000 ) ] ) ;
90-
91- try {
92- this . treatment = extensions ? JSON . parse ( extensions ) : { extensions : [ ] } ;
93- } catch {
77+ const featuredExtensions = this . productService . featuredExtensions ;
78+ if ( ! featuredExtensions ) {
79+ this . _isInitialized = true ;
80+ return ;
9481 }
9582
96- this . title = extensionListTitle ?? localize ( 'gettingStarted.featuredTitle' , 'Featured' ) ;
97-
98- if ( this . treatment ?. extensions && Array . isArray ( this . treatment . extensions ) ) {
99- const installed = await this . extensionManagementService . getInstalled ( ) ;
100- for ( const extension of this . treatment . extensions ) {
101- if ( installed . some ( e => ExtensionIdentifier . equals ( e . identifier . id , extension ) ) ) {
102- this . ignoredExtensions . add ( extension ) ;
83+ await this . extensionService . whenInstalledExtensionsRegistered ( ) ;
84+ const installed = await this . extensionManagementService . getInstalled ( ) ;
85+ for ( const extension of featuredExtensions ) {
86+ if ( installed . some ( e => ExtensionIdentifier . equals ( e . identifier . id , extension . id ) ) ) {
87+ this . ignoredExtensions . add ( extension . id ) ;
88+ }
89+ else {
90+ let galleryExtension : IGalleryExtension | undefined ;
91+ try {
92+ galleryExtension = ( await this . galleryService . getExtensions ( [ { id : extension . id } ] , CancellationToken . None ) ) [ 0 ] ;
93+ } catch ( err ) {
94+ continue ;
10395 }
104- else {
105- let galleryExtension : IGalleryExtension | undefined ;
106- try {
107- galleryExtension = ( await this . galleryService . getExtensions ( [ { id : extension } ] , CancellationToken . None ) ) [ 0 ] ;
108- } catch ( err ) {
109- continue ;
110- }
111- if ( ! await this . extensionManagementService . canInstall ( galleryExtension ) ) {
112- this . ignoredExtensions . add ( extension ) ;
113- }
96+ if ( ! await this . extensionManagementService . canInstall ( galleryExtension ) ) {
97+ this . ignoredExtensions . add ( extension . id ) ;
11498 }
11599 }
116100 }
117-
118101 this . _isInitialized = true ;
119102 }
120103
121- private async resolveExtension ( extensionId : string ) : Promise < IFeaturedExtension | undefined > {
122-
123- const productMetadata = this . productService . featuredExtensions ?. find ( e => ExtensionIdentifier . equals ( e . id , extensionId ) ) ;
104+ private async resolveExtension ( productMetadata : IFeaturedExtension ) : Promise < IFeaturedExtension | undefined > {
124105
125- const title = productMetadata ? .title ?? await this . getMetadata ( extensionId , FeaturedExtensionMetadataType . Title ) ;
126- const description = productMetadata ? .description ?? await this . getMetadata ( extensionId , FeaturedExtensionMetadataType . Description ) ;
127- const imagePath = productMetadata ? .imagePath ?? await this . getMetadata ( extensionId , FeaturedExtensionMetadataType . ImagePath ) ;
106+ const title = productMetadata . title ?? await this . getMetadata ( productMetadata . id , FeaturedExtensionMetadataType . Title ) ;
107+ const description = productMetadata . description ?? await this . getMetadata ( productMetadata . id , FeaturedExtensionMetadataType . Description ) ;
108+ const imagePath = productMetadata . imagePath ?? await this . getMetadata ( productMetadata . id , FeaturedExtensionMetadataType . ImagePath ) ;
128109
129110 if ( title && description && imagePath ) {
130111 return {
131- id : extensionId ,
112+ id : productMetadata . id ,
132113 title : title ,
133114 description : description ,
134115 imagePath : imagePath ,
0 commit comments