diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css index 5b4d1fcb93d46..11e9673c13c7c 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.css @@ -112,6 +112,12 @@ font-size: 32px; } +.monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide .getting-started-category img.category-icon { + margin-right: 10px; + max-width: 32px; + max-height: 32px; +} + .monaco-workbench .part.editor > .content .gettingStartedContainer .gettingStartedSlide.detail { display: flex; flex-direction: column; diff --git a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts index 3b5d67fe4103b..9982c636fc5fa 100644 --- a/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts +++ b/src/vs/workbench/contrib/welcome/gettingStarted/browser/gettingStarted.ts @@ -27,6 +27,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage'; import { CancellationToken } from 'vs/base/common/cancellation'; import { Schemas } from 'vs/base/common/network'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { IGettingStartedCategoryDescriptor } from 'vs/workbench/services/gettingStarted/common/gettingStartedRegistry'; const SLIDE_TRANSITION_TIME_MS = 250; const configurationKey = 'workbench.startupEditor'; @@ -323,7 +324,8 @@ export class GettingStartedPage extends EditorPane { 'x-dispatch': 'selectCategory:' + category.id, 'role': 'listitem', }, - $(ThemeIcon.asCSSSelector(category.icon), {}), categoryDescriptionElement); + this.iconWidgetFor(category), + categoryDescriptionElement); }); const categoryScrollContainer = $('.getting-started-categories-scrolling-container'); @@ -427,6 +429,10 @@ export class GettingStartedPage extends EditorPane { }); } + private iconWidgetFor(category: IGettingStartedCategoryDescriptor) { + return category.icon.type === 'icon' ? $(ThemeIcon.asCSSSelector(category.icon.icon)) : $('img.category-icon', { src: category.icon.path }); + } + private buildCategorySlide(categoryID: string, selectedItem?: string) { const category = this.gettingStartedCategories.find(category => category.id === categoryID); if (!category) { throw Error('could not find category with ID ' + categoryID); } @@ -440,7 +446,7 @@ export class GettingStartedPage extends EditorPane { detailTitle.appendChild( $('.getting-started-category', {}, - $(ThemeIcon.asCSSSelector(category.icon), {}), + this.iconWidgetFor(category), $('.category-description-container', {}, $('h2.category-title', {}, category.title), $('.category-description.description', {}, category.description)))); diff --git a/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts b/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts index 3e98f0e75c1c1..7e5638ba1d195 100644 --- a/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts +++ b/src/vs/workbench/services/gettingStarted/common/gettingStartedContent.ts @@ -270,16 +270,5 @@ export const content: GettingStartedContent = [ } ] } - }, - - { - id: 'ExtensionContrib', - title: localize('gettingStarted.extensionContrib.title', "Discover Your Extensions"), - icon: extensionsIcon, - description: localize('gettingStarted.extensionContrib.description', "Learn about features contributed by installed extensions."), - content: { - type: 'items', - items: [] - } } ]; diff --git a/src/vs/workbench/services/gettingStarted/common/gettingStartedRegistry.ts b/src/vs/workbench/services/gettingStarted/common/gettingStartedRegistry.ts index f77f204417efb..b8a4867d9d0e2 100644 --- a/src/vs/workbench/services/gettingStarted/common/gettingStartedRegistry.ts +++ b/src/vs/workbench/services/gettingStarted/common/gettingStartedRegistry.ts @@ -37,7 +37,9 @@ export interface IGettingStartedCategoryDescriptor { id: GettingStartedCategory | string title: string description: string - icon: ThemeIcon + icon: + | { type: 'icon', icon: ThemeIcon } + | { type: 'image', path: string } when: ContextKeyExpression content: | { type: 'items' } @@ -48,7 +50,9 @@ export interface IGettingStartedCategory { id: GettingStartedCategory | string title: string description: string - icon: ThemeIcon + icon: + | { type: 'icon', icon: ThemeIcon } + | { type: 'image', path: string } when: ContextKeyExpression content: | { type: 'items', items: IGettingStartedTask[] } @@ -129,6 +133,7 @@ content.forEach(category => { registryImpl.registerCategory({ ...category, + icon: { type: 'icon', icon: category.icon }, when: ContextKeyExpr.deserialize(category.when) ?? ContextKeyExpr.true() }); diff --git a/src/vs/workbench/services/gettingStarted/common/gettingStartedService.ts b/src/vs/workbench/services/gettingStarted/common/gettingStartedService.ts index 8377ec8f9bf94..fbf2f212572dc 100644 --- a/src/vs/workbench/services/gettingStarted/common/gettingStartedService.ts +++ b/src/vs/workbench/services/gettingStarted/common/gettingStartedService.ts @@ -19,6 +19,8 @@ import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensio import { URI } from 'vs/base/common/uri'; import { joinPath } from 'vs/base/common/resources'; import { FileAccess } from 'vs/base/common/network'; +import { localize } from 'vs/nls'; +import { DefaultIconPath } from 'vs/platform/extensionManagement/common/extensionManagement'; export const IGettingStartedService = createDecorator('gettingStartedService'); @@ -141,6 +143,21 @@ export class GettingStartedService extends Disposable implements IGettingStarted return; } + const categoryID = `EXTContrib-${extension.identifier.value}`; + + this.registry.registerCategory({ + content: { type: 'items' }, + description: localize('extContrib', "Learn more about {0}!", extension.displayName ?? extension.name), + title: extension.displayName || extension.name, + id: categoryID, + icon: { + type: 'image', + path: extension.icon + ? FileAccess.asBrowserUri(joinPath(extension.extensionLocation, extension.icon)).toString(true) + : DefaultIconPath + }, + when: ContextKeyExpr.true(), + }); extension.contributes?.gettingStarted.forEach((content, index) => { this.registry.registerTask({ button: content.button, @@ -150,7 +167,7 @@ export class GettingStartedService extends Disposable implements IGettingStarted id: content.id, title: content.title, when: ContextKeyExpr.deserialize(content.when) ?? ContextKeyExpr.true(), - category: 'ExtensionContrib', + category: categoryID, order: index, }); });