mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-26 06:40:30 -04:00
* Merge from vscode e388c734f30757875976c7e326d6cfeee77710de * fix yarn lcoks * remove small issue
257 lines
9.0 KiB
TypeScript
257 lines
9.0 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import 'vs/css!./media/extensionsWidgets';
|
|
import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
|
|
import { IExtension, IExtensionsWorkbenchService, IExtensionContainer } from '../common/extensions';
|
|
import { append, $, addClass } from 'vs/base/browser/dom';
|
|
import * as platform from 'vs/base/common/platform';
|
|
import { localize } from 'vs/nls';
|
|
import { IExtensionManagementServerService, IExtensionTipsService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
|
import { ILabelService } from 'vs/platform/label/common/label';
|
|
import { extensionButtonProminentBackground, extensionButtonProminentForeground } from 'vs/workbench/contrib/extensions/electron-browser/extensionsActions';
|
|
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
|
import { STATUS_BAR_HOST_NAME_BACKGROUND, STATUS_BAR_FOREGROUND, STATUS_BAR_NO_FOLDER_FOREGROUND } from 'vs/workbench/common/theme';
|
|
import { IWorkspaceContextService, WorkbenchState } from 'vs/platform/workspace/common/workspace';
|
|
import { REMOTE_HOST_SCHEME } from 'vs/platform/remote/common/remoteHosts';
|
|
import { IWindowService } from 'vs/platform/windows/common/windows';
|
|
|
|
export abstract class ExtensionWidget extends Disposable implements IExtensionContainer {
|
|
private _extension: IExtension;
|
|
get extension(): IExtension { return this._extension; }
|
|
set extension(extension: IExtension) { this._extension = extension; this.update(); }
|
|
update(): void { this.render(); }
|
|
abstract render(): void;
|
|
}
|
|
|
|
export class Label extends ExtensionWidget {
|
|
|
|
constructor(
|
|
private element: HTMLElement,
|
|
private fn: (extension: IExtension) => string,
|
|
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService
|
|
) {
|
|
super();
|
|
this.render();
|
|
}
|
|
|
|
render(): void {
|
|
this.element.textContent = this.extension ? this.fn(this.extension) : '';
|
|
}
|
|
}
|
|
|
|
export class InstallCountWidget extends ExtensionWidget {
|
|
|
|
constructor(
|
|
private container: HTMLElement,
|
|
private small: boolean,
|
|
@IExtensionsWorkbenchService extensionsWorkbenchService: IExtensionsWorkbenchService
|
|
) {
|
|
super();
|
|
addClass(container, 'extension-install-count');
|
|
this.render();
|
|
}
|
|
|
|
render(): void {
|
|
this.container.innerHTML = '';
|
|
|
|
if (!this.extension) {
|
|
return;
|
|
}
|
|
|
|
const installCount = this.extension.installCount;
|
|
|
|
if (installCount === undefined) {
|
|
return;
|
|
}
|
|
|
|
let installLabel: string;
|
|
|
|
if (this.small) {
|
|
if (installCount > 1000000) {
|
|
installLabel = `${Math.floor(installCount / 100000) / 10}M`;
|
|
} else if (installCount > 1000) {
|
|
installLabel = `${Math.floor(installCount / 1000)}K`;
|
|
} else {
|
|
installLabel = String(installCount);
|
|
}
|
|
}
|
|
else {
|
|
installLabel = installCount.toLocaleString(platform.locale);
|
|
}
|
|
|
|
append(this.container, $('span.octicon.octicon-cloud-download'));
|
|
const count = append(this.container, $('span.count'));
|
|
count.textContent = installLabel;
|
|
}
|
|
}
|
|
|
|
export class RatingsWidget extends ExtensionWidget {
|
|
|
|
constructor(
|
|
private container: HTMLElement,
|
|
private small: boolean
|
|
) {
|
|
super();
|
|
addClass(container, 'extension-ratings');
|
|
|
|
if (this.small) {
|
|
addClass(container, 'small');
|
|
}
|
|
|
|
this.render();
|
|
}
|
|
|
|
render(): void {
|
|
this.container.innerHTML = '';
|
|
|
|
if (!this.extension) {
|
|
return;
|
|
}
|
|
|
|
if (this.extension.rating === undefined) {
|
|
return;
|
|
}
|
|
|
|
if (this.small && !this.extension.ratingCount) {
|
|
return;
|
|
}
|
|
|
|
const rating = Math.round(this.extension.rating * 2) / 2;
|
|
|
|
if (this.small) {
|
|
append(this.container, $('span.full.star'));
|
|
|
|
const count = append(this.container, $('span.count'));
|
|
count.textContent = String(rating);
|
|
} else {
|
|
for (let i = 1; i <= 5; i++) {
|
|
if (rating >= i) {
|
|
append(this.container, $('span.full.star'));
|
|
} else if (rating >= i - 0.5) {
|
|
append(this.container, $('span.half.star'));
|
|
} else {
|
|
append(this.container, $('span.empty.star'));
|
|
}
|
|
}
|
|
}
|
|
this.container.title = this.extension.ratingCount === 1 ? localize('ratedBySingleUser', "Rated by 1 user")
|
|
: typeof this.extension.ratingCount === 'number' && this.extension.ratingCount > 1 ? localize('ratedByUsers', "Rated by {0} users", this.extension.ratingCount) : localize('noRating', "No rating");
|
|
}
|
|
}
|
|
|
|
export class RecommendationWidget extends ExtensionWidget {
|
|
|
|
private element?: HTMLElement;
|
|
private disposables: IDisposable[] = [];
|
|
|
|
constructor(
|
|
private parent: HTMLElement,
|
|
@IThemeService private readonly themeService: IThemeService,
|
|
@IExtensionTipsService private readonly extensionTipsService: IExtensionTipsService
|
|
) {
|
|
super();
|
|
this.render();
|
|
this._register(toDisposable(() => this.clear()));
|
|
this._register(this.extensionTipsService.onRecommendationChange(() => this.render()));
|
|
}
|
|
|
|
private clear(): void {
|
|
this.parent.title = '';
|
|
this.parent.setAttribute('aria-label', this.extension ? localize('viewExtensionDetailsAria', "{0}. Press enter for extension details.", this.extension.displayName) : '');
|
|
if (this.element) {
|
|
this.parent.removeChild(this.element);
|
|
}
|
|
this.element = undefined;
|
|
this.disposables = dispose(this.disposables);
|
|
}
|
|
|
|
render(): void {
|
|
this.clear();
|
|
if (!this.extension) {
|
|
return;
|
|
}
|
|
const extRecommendations = this.extensionTipsService.getAllRecommendationsWithReason();
|
|
if (extRecommendations[this.extension.identifier.id.toLowerCase()]) {
|
|
this.element = append(this.parent, $('div.bookmark'));
|
|
const recommendation = append(this.element, $('.recommendation'));
|
|
append(recommendation, $('span.octicon.octicon-star'));
|
|
const applyBookmarkStyle = (theme) => {
|
|
const bgColor = theme.getColor(extensionButtonProminentBackground);
|
|
const fgColor = theme.getColor(extensionButtonProminentForeground);
|
|
recommendation.style.borderTopColor = bgColor ? bgColor.toString() : 'transparent';
|
|
recommendation.style.color = fgColor ? fgColor.toString() : 'white';
|
|
};
|
|
applyBookmarkStyle(this.themeService.getTheme());
|
|
this.themeService.onThemeChange(applyBookmarkStyle, this, this.disposables);
|
|
this.parent.title = extRecommendations[this.extension.identifier.id.toLowerCase()].reasonText;
|
|
this.parent.setAttribute('aria-label', localize('viewRecommendedExtensionDetailsAria', "{0}. {1} Press enter for extension details.", this.extension.displayName, extRecommendations[this.extension.identifier.id.toLowerCase()].reasonText));
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
export class RemoteBadgeWidget extends ExtensionWidget {
|
|
|
|
private element: HTMLElement | null;
|
|
private disposables: IDisposable[] = [];
|
|
|
|
constructor(
|
|
private parent: HTMLElement,
|
|
@ILabelService private readonly labelService: ILabelService,
|
|
@IThemeService private readonly themeService: IThemeService,
|
|
@IExtensionManagementServerService private readonly extensionManagementServerService: IExtensionManagementServerService,
|
|
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
|
|
@IWindowService private readonly windowService: IWindowService
|
|
) {
|
|
super();
|
|
this.render();
|
|
this._register(toDisposable(() => this.clear()));
|
|
}
|
|
|
|
private clear(): void {
|
|
if (this.element) {
|
|
this.parent.removeChild(this.element);
|
|
}
|
|
this.element = null;
|
|
this.disposables = dispose(this.disposables);
|
|
}
|
|
|
|
render(): void {
|
|
this.clear();
|
|
if (!this.extension || !this.extension.local) {
|
|
return;
|
|
}
|
|
const server = this.extensionManagementServerService.getExtensionManagementServer(this.extension.local.location);
|
|
if (server === this.extensionManagementServerService.remoteExtensionManagementServer) {
|
|
this.element = append(this.parent, $('div.extension-remote-badge'));
|
|
append(this.element, $('span.octicon.octicon-file-symlink-directory'));
|
|
|
|
const applyBadgeStyle = () => {
|
|
if (!this.element) {
|
|
return;
|
|
}
|
|
const bgColor = this.themeService.getTheme().getColor(STATUS_BAR_HOST_NAME_BACKGROUND);
|
|
const fgColor = this.workspaceContextService.getWorkbenchState() === WorkbenchState.EMPTY ? this.themeService.getTheme().getColor(STATUS_BAR_NO_FOLDER_FOREGROUND) : this.themeService.getTheme().getColor(STATUS_BAR_FOREGROUND);
|
|
this.element.style.backgroundColor = bgColor ? bgColor.toString() : '';
|
|
this.element.style.color = fgColor ? fgColor.toString() : '';
|
|
};
|
|
applyBadgeStyle();
|
|
this.themeService.onThemeChange(applyBadgeStyle, this, this.disposables);
|
|
this.workspaceContextService.onDidChangeWorkbenchState(applyBadgeStyle, this, this.disposables);
|
|
|
|
const updateTitle = () => {
|
|
if (this.element) {
|
|
this.element.title = localize('remote extension title', "Extension in {0}", this.labelService.getHostLabel(REMOTE_HOST_SCHEME, this.windowService.getConfiguration().remoteAuthority));
|
|
}
|
|
};
|
|
this.labelService.onDidChangeFormatters(() => updateTitle(), this, this.disposables);
|
|
updateTitle();
|
|
}
|
|
}
|
|
|
|
}
|