diff --git a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts index 8d9dd6f1b87563d0942f883237e7a0eb86f326f5..110810654c9b5ace41d53a242683eafd07bfcc3b 100644 --- a/src/vs/workbench/contrib/extensions/browser/extensionsList.ts +++ b/src/vs/workbench/contrib/extensions/browser/extensionsList.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { localize } from 'vs/nls'; import { append, $, addClass, removeClass, toggleClass } from 'vs/base/browser/dom'; import { IDisposable, dispose, combinedDisposable } from 'vs/base/common/lifecycle'; import { IAction } from 'vs/base/common/actions'; @@ -19,7 +20,9 @@ import { Label, RatingsWidget, InstallCountWidget, RecommendationWidget, RemoteB import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement'; import { INotificationService } from 'vs/platform/notification/common/notification'; -import { isLanguagePackExtension } from 'vs/platform/extensions/common/extensions'; +import { isLanguagePackExtension, IExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; +import { CodiconLabel } from 'vs/base/browser/ui/codiconLabel/codiconLabel'; +import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; export interface IExtensionsViewState { onFocus: Event; @@ -34,6 +37,7 @@ export interface ITemplateData { installCount: HTMLElement; ratings: HTMLElement; author: HTMLElement; + syncIgnored: HTMLElement; description: HTMLElement; extension: IExtension | null; disposables: IDisposable[]; @@ -56,7 +60,8 @@ export class Renderer implements IPagedRenderer { @INotificationService private readonly notificationService: INotificationService, @IExtensionService private readonly extensionService: IExtensionService, @IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService, - @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService + @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, + @IConfigurationService private readonly configurationService: IConfigurationService, ) { } get templateId() { return 'extension'; } @@ -78,6 +83,9 @@ export class Renderer implements IPagedRenderer { const description = append(details, $('.description.ellipsis')); const footer = append(details, $('.footer')); const author = append(footer, $('.author.ellipsis')); + const syncIgnored = append(footer, $('.sync-ignored.ellipsis')); + const syncIgnoredLabel = new CodiconLabel(syncIgnored); + syncIgnoredLabel.text = '$(eye-closed) ' + localize('extensionSyncIgnoredLabel', 'Sync: Ignored'); const actionbar = new ActionBar(footer, { animated: false, actionViewItemProvider: (action: IAction) => { @@ -119,7 +127,7 @@ export class Renderer implements IPagedRenderer { const disposables = combinedDisposable(...actions, ...widgets, actionbar, extensionContainers, extensionTooltipAction); return { - root, element, icon, name, installCount, ratings, author, description, disposables: [disposables], actionbar, + root, element, icon, name, installCount, syncIgnored, ratings, author, description, disposables: [disposables], actionbar, extensionDisposables: [], set extension(extension: IExtension) { extensionContainers.extension = extension; @@ -197,9 +205,25 @@ export class Renderer implements IPagedRenderer { data.actionbar.viewItems.forEach(item => (item).setFocus(false)); } }, this, data.extensionDisposables); + + + this.updateExtensionIgnored(extension, data); + this.configurationService.onDidChangeConfiguration(e => { + if (e.affectedKeys.includes('sync.ignoredExtensions')) { + this.updateExtensionIgnored(extension, data); + } + }, data.extensionDisposables); } disposeTemplate(data: ITemplateData): void { data.disposables = dispose(data.disposables); } + + private updateExtensionIgnored(extension: IExtension, data: ITemplateData): void { + data.syncIgnored.style.display = this.extensionIsIgnored(extension.identifier) ? 'block' : 'none'; + } + + private extensionIsIgnored(identifier: IExtensionIdentifier): boolean { + return this.configurationService.getValue('sync.ignoredExtensions').some(id => areSameExtensions({ id }, identifier)); + } } diff --git a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css index f972d5d1a8af0c384fdd10789e0419acd6c8b752..c86d44c5b1db18e6d2c4a030c553142c72b6a11a 100644 --- a/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css +++ b/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css @@ -254,6 +254,15 @@ font-weight: 600; } +.extensions-viewlet > .extensions .extension > .details > .footer > .sync-ignored { + font-size: 11px; +} + +.extensions-viewlet > .extensions .extension > .details > .footer > .sync-ignored > .codicon { + font-size: 14px; + vertical-align: text-top; +} + .extensions-viewlet > .extensions .selected .extension > .details > .footer > .author, .extensions-viewlet > .extensions .selected.focused .extension > .details > .footer > .author { opacity: 1;