提交 4f22d447 编写于 作者: J Joao Moreno

galleryExtension.iconUrlFallback related to #10180

上级 8e4b3e0a
......@@ -33,6 +33,7 @@ export interface IGalleryExtensionAssets {
readme: string;
download: string;
icon: string;
iconFallback: string;
license: string;
}
......
......@@ -181,11 +181,25 @@ function getAssetSource(files: IRawGalleryExtensionFile[], type: string): string
function toExtension(galleryExtension: IRawGalleryExtension, extensionsGalleryUrl: string, downloadHeaders: { [key: string]: string; }): IGalleryExtension {
const [version] = galleryExtension.versions;
let iconFallback = getAssetSource(version.files, AssetType.Icon);
let icon: string;
if (iconFallback) {
const parsedUrl = url.parse(iconFallback, true);
parsedUrl.search = undefined;
parsedUrl.query['redirect'] = 'true';
icon = url.format(parsedUrl);
} else {
iconFallback = icon = require.toUrl('./media/defaultIcon.png');
}
const assets = {
manifest: getAssetSource(version.files, AssetType.Manifest),
readme: getAssetSource(version.files, AssetType.Details),
download: `${ getAssetSource(version.files, AssetType.VSIX) }?install=true`,
icon: getAssetSource(version.files, AssetType.Icon) || require.toUrl('./media/defaultIcon.png'),
icon,
iconFallback,
license: getAssetSource(version.files, AssetType.License)
};
......
......@@ -12,6 +12,8 @@ import { marked } from 'vs/base/common/marked/marked';
import { onUnexpectedError } from 'vs/base/common/errors';
import { IDisposable, empty, dispose, toDisposable } from 'vs/base/common/lifecycle';
import { Builder } from 'vs/base/browser/builder';
import { once } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { append, emmet as $, addClass, removeClass, finalHandler } from 'vs/base/browser/dom';
import { BaseEditor } from 'vs/workbench/browser/parts/editor/baseEditor';
import { IViewlet } from 'vs/workbench/common/viewlet';
......@@ -48,7 +50,7 @@ export class ExtensionEditor extends BaseEditor {
static ID: string = 'workbench.editor.extension';
private icon: HTMLElement;
private icon: HTMLImageElement;
private name: HTMLAnchorElement;
private license: HTMLAnchorElement;
private publisher: HTMLAnchorElement;
......@@ -88,7 +90,7 @@ export class ExtensionEditor extends BaseEditor {
const root = append(container, $('.extension-editor'));
const header = append(root, $('.header'));
this.icon = append(header, $('.icon'));
this.icon = append(header, $<HTMLImageElement>('img.icon'));
const details = append(header, $('.details'));
const title = append(details, $('.title'));
......@@ -124,7 +126,10 @@ export class ExtensionEditor extends BaseEditor {
const extension = input.extension;
this.telemetryService.publicLog('extensionGallery:openExtension', extension.telemetryData);
this.icon.style.backgroundImage = `url("${ extension.iconUrl }")`;
const onError = once(domEvent(this.icon, 'error'));
onError(() => this.icon.src = extension.iconUrlFallback, null, this.transientDisposables);
this.icon.src = extension.iconUrl;
this.name.textContent = extension.displayName;
this.publisher.textContent = extension.publisherDisplayName;
this.description.textContent = extension.description;
......
......@@ -34,6 +34,7 @@ export interface IExtension {
description: string;
readmeUrl: string;
iconUrl: string;
iconUrlFallback: string;
licenseUrl: string;
installCount: number;
rating: number;
......
......@@ -12,6 +12,8 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
import { IMessageService, Severity } from 'vs/platform/message/common/message';
import { IDelegate } from 'vs/base/browser/ui/list/list';
import { IPagedRenderer } from 'vs/base/browser/ui/list/listPaging';
import { once } from 'vs/base/common/event';
import { domEvent } from 'vs/base/browser/event';
import { IExtension } from './extensions';
import { CombinedInstallAction, UpdateAction, EnableAction } from './extensionsActions';
import { Label, RatingsWidget, InstallWidget } from './extensionsWidgets';
......@@ -27,6 +29,7 @@ export interface ITemplateData {
description: HTMLElement;
extension: IExtension;
disposables: IDisposable[];
extensionDisposables: IDisposable[];
}
export class Delegate implements IDelegate<IExtension> {
......@@ -74,6 +77,7 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
return {
element, icon, name, installCount, ratings, author, description, disposables,
extensionDisposables: [],
set extension(extension: IExtension) {
versionWidget.extension = extension;
installCountWidget.extension = extension;
......@@ -87,6 +91,8 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
renderPlaceholder(index: number, data: ITemplateData): void {
addClass(data.element, 'loading');
data.extensionDisposables = dispose(data.extensionDisposables);
data.icon.src = '';
data.name.textContent = '';
data.author.textContent = '';
......@@ -98,6 +104,11 @@ export class Renderer implements IPagedRenderer<IExtension, ITemplateData> {
renderElement(extension: IExtension, index: number, data: ITemplateData): void {
removeClass(data.element, 'loading');
data.extensionDisposables = dispose(data.extensionDisposables);
const onError = once(domEvent(data.icon, 'error'));
onError(() => data.icon.src = extension.iconUrlFallback, null, data.extensionDisposables);
data.icon.src = extension.iconUrl;
if (!data.icon.complete) {
......
......@@ -86,11 +86,28 @@ class Extension implements IExtension {
}
get iconUrl(): string {
if (this.local && this.local.manifest.icon) {
return URI.file(path.join(this.local.path, this.local.manifest.icon)).toString();
}
return this.localIconUrl || this.galleryIconUrl || this.defaultIconUrl;
}
get iconUrlFallback(): string {
return this.localIconUrl || this.galleryIconUrlFallback || this.defaultIconUrl;
}
private get localIconUrl(): string {
return this.local && this.local.manifest.icon
&& URI.file(path.join(this.local.path, this.local.manifest.icon)).toString();
}
private get galleryIconUrl(): string {
return this.gallery && this.gallery.assets.icon;
}
private get galleryIconUrlFallback(): string {
return this.gallery && this.gallery.assets.iconFallback;
}
return this.gallery ? this.gallery.assets.icon : require.toUrl('./media/defaultIcon.png');
private get defaultIconUrl(): string {
return require.toUrl('./media/defaultIcon.png');
}
get licenseUrl(): string {
......
......@@ -24,10 +24,7 @@
.extension-editor > .header > .icon {
height: 128px;
width: 128px;
min-width: 128px;
background-size: 128px;
background-repeat: no-repeat;
background-position: center center;
object-fit: contain;
}
.extension-editor > .header > .details {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册