Use icon image where available (#4721)

* Use iconimg where available

* Adjust margin for icon

* remove log

* Fix property casing

* Add blue topbar, and generalize properties

* Inline checks

* inline property functions

* Limit compute

* Linting

* lovercase const

* Review comments and move update dot to line

* Add roboto font to hassio

* Fix update and stopped styles colliding

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Joakim Sørensen 2020-02-04 12:36:09 +01:00 committed by GitHub
parent 862044ca23
commit f1a1654371
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 136 additions and 69 deletions

View File

@ -39,6 +39,7 @@ class HassioAddonRepositoryEl extends LitElement {
protected render(): TemplateResult { protected render(): TemplateResult {
const repo = this.repo; const repo = this.repo;
const addons = this._getAddons(this.addons, this.filter); const addons = this._getAddons(this.addons, this.filter);
const ha105pluss = this._computeHA105plus;
if (this.filter && addons.length < 1) { if (this.filter && addons.length < 1) {
return html` return html`
@ -64,7 +65,7 @@ class HassioAddonRepositoryEl extends LitElement {
<paper-card <paper-card
.addon=${addon} .addon=${addon}
class=${addon.available ? "" : "not_available"} class=${addon.available ? "" : "not_available"}
@click=${this.addonTapped} @click=${this._addonTapped}
> >
<div class="card-content"> <div class="card-content">
<hassio-card-content <hassio-card-content
@ -72,9 +73,34 @@ class HassioAddonRepositoryEl extends LitElement {
.title=${addon.name} .title=${addon.name}
.description=${addon.description} .description=${addon.description}
.available=${addon.available} .available=${addon.available}
.icon=${this.computeIcon(addon)} .icon=${addon.installed && addon.installed !== addon.version
.iconTitle=${this.computeIconTitle(addon)} ? "hassio:arrow-up-bold-circle"
.iconClass=${this.computeIconClass(addon)} : "hassio:puzzle"}
.iconTitle=${addon.installed
? addon.installed !== addon.version
? "New version available"
: "Add-on is installed"
: addon.available
? "Add-on is not installed"
: "Add-on is not available on your system"}
.iconClass=${addon.installed
? addon.installed !== addon.version
? "update"
: "installed"
: !addon.available
? "not_available"
: ""}
.iconImage=${ha105pluss && addon.icon
? `/api/hassio/addons/${addon.slug}/icon`
: undefined}
.showTopbar=${addon.installed || !addon.available}
.topbarClass=${addon.installed
? addon.installed !== addon.version
? "update"
: "installed"
: !addon.available
? "unavailable"
: ""}
></hassio-card-content> ></hassio-card-content>
</div> </div>
</paper-card> </paper-card>
@ -85,34 +111,15 @@ class HassioAddonRepositoryEl extends LitElement {
`; `;
} }
private computeIcon(addon) { private _addonTapped(ev) {
return addon.installed && addon.installed !== addon.version
? "hassio:arrow-up-bold-circle"
: "hassio:puzzle";
}
private computeIconTitle(addon) {
if (addon.installed) {
return addon.installed !== addon.version
? "New version available"
: "Add-on is installed";
}
return addon.available
? "Add-on is not installed"
: "Add-on is not available on your system";
}
private computeIconClass(addon) {
if (addon.installed) {
return addon.installed !== addon.version ? "update" : "installed";
}
return !addon.available ? "not_available" : "";
}
private addonTapped(ev) {
navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`); navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`);
} }
private get _computeHA105plus(): boolean {
const [major, minor] = this.hass.config.version.split(".", 2);
return Number(major) > 0 || (major === "0" && Number(minor) >= 105);
}
static get styles(): CSSResultArray { static get styles(): CSSResultArray {
return [ return [
hassioStyle, hassioStyle,

View File

@ -454,7 +454,6 @@ class HassioAddonInfo extends LitElement {
<ha-progress-button <ha-progress-button
.disabled=${!this.addon.available} .disabled=${!this.addon.available}
.progress=${this._installing} .progress=${this._installing}
class="right"
@click=${this._installClicked} @click=${this._installClicked}
> >
Install Install

View File

@ -7,6 +7,7 @@ import {
property, property,
customElement, customElement,
} from "lit-element"; } from "lit-element";
import { classMap } from "lit-html/directives/class-map";
import "@polymer/iron-icon/iron-icon"; import "@polymer/iron-icon/iron-icon";
import "../../../src/components/ha-relative-time"; import "../../../src/components/ha-relative-time";
@ -17,21 +18,40 @@ class HassioCardContent extends LitElement {
@property() public hass!: HomeAssistant; @property() public hass!: HomeAssistant;
@property() public title!: string; @property() public title!: string;
@property() public description?: string; @property() public description?: string;
@property({ type: Boolean }) public available?: boolean; @property({ type: Boolean }) public available: boolean = true;
@property({ type: Boolean }) public showTopbar: boolean = false;
@property() public topbarClass?: string;
@property() public datetime?: string; @property() public datetime?: string;
@property() public iconTitle?: string; @property() public iconTitle?: string;
@property() public iconClass?: string; @property() public iconClass?: string;
@property() public icon = "hass:help-circle"; @property() public icon = "hass:help-circle";
@property() public iconImage?: string;
protected render(): TemplateResult { protected render(): TemplateResult {
return html` return html`
<iron-icon ${this.showTopbar
class=${this.iconClass} ? html`
.icon=${this.icon} <div class="topbar ${this.topbarClass}"></div>
.title=${this.iconTitle} `
></iron-icon> : ""}
${this.iconImage
? html`
<div class="icon_image ${this.iconClass}">
<img src="${this.iconImage}" title="${this.iconTitle}" />
<div></div>
</div>
`
: html`
<iron-icon
class=${this.iconClass}
.icon=${this.icon}
.title=${this.iconTitle}
></iron-icon>
`}
<div> <div>
<div class="title">${this.title}</div> <div class="title">
${this.title}
</div>
<div class="addition"> <div class="addition">
${this.description} ${this.description}
${/* treat as available when undefined */ ${/* treat as available when undefined */
@ -53,8 +73,9 @@ class HassioCardContent extends LitElement {
static get styles(): CSSResult { static get styles(): CSSResult {
return css` return css`
iron-icon { iron-icon {
margin-right: 16px; margin-right: 24px;
margin-top: 16px; margin-left: 8px;
margin-top: 12px;
float: left; float: left;
color: var(--secondary-text-color); color: var(--secondary-text-color);
} }
@ -88,6 +109,44 @@ class HassioCardContent extends LitElement {
ha-relative-time { ha-relative-time {
display: block; display: block;
} }
.icon_image img {
max-height: 40px;
max-width: 40px;
margin-top: 4px;
margin-right: 16px;
float: left;
}
.icon_image.stopped,
.icon_image.not_available {
filter: grayscale(1);
}
.dot {
position: absolute;
background-color: var(--paper-orange-400);
width: 12px;
height: 12px;
top: 8px;
right: 8px;
border-radius: 50%;
}
.topbar {
position: absolute;
width: 100%;
height: 2px;
top: 0;
left: 0;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.topbar.installed {
background-color: var(--primary-color);
}
.topbar.update {
background-color: var(--accent-color);
}
.topbar.unavailable {
background-color: var(--error-color);
}
`; `;
} }
} }

View File

@ -22,6 +22,9 @@ class HassioAddons extends LitElement {
@property() public addons?: HassioAddonInfo[]; @property() public addons?: HassioAddonInfo[];
protected render(): TemplateResult { protected render(): TemplateResult {
const [major, minor] = this.hass.config.version.split(".", 2);
const ha105pluss =
Number(major) > 0 || (major === "0" && Number(minor) >= 105);
return html` return html`
<div class="content"> <div class="content">
<h1>Add-ons</h1> <h1>Add-ons</h1>
@ -44,12 +47,30 @@ class HassioAddons extends LitElement {
<div class="card-content"> <div class="card-content">
<hassio-card-content <hassio-card-content
.hass=${this.hass} .hass=${this.hass}
title=${addon.name} .title=${addon.name}
description=${addon.description} .description=${addon.description}
?available=${addon.available} available
icon=${this._computeIcon(addon)} .showTopbar=${addon.installed !== addon.version}
.iconTitle=${this._computeIconTitle(addon)} topbarClass="update"
.iconClass=${this._computeIconClass(addon)} .icon=${addon.installed !== addon.version
? "hassio:arrow-up-bold-circle"
: "hassio:puzzle"}
.iconTitle=${addon.state !== "started"
? "Add-on is stopped"
: addon.installed !== addon.version
? "New version available"
: "Add-on is running"}
.iconClass=${addon.installed &&
addon.installed !== addon.version
? addon.state === "started"
? "update"
: "update stopped"
: addon.installed && addon.state === "started"
? "running"
: "stopped"}
.iconImage=${ha105pluss && addon.icon
? `/api/hassio/addons/${addon.slug}/icon`
: undefined}
></hassio-card-content> ></hassio-card-content>
</div> </div>
</paper-card> </paper-card>
@ -72,28 +93,6 @@ class HassioAddons extends LitElement {
]; ];
} }
private _computeIcon(addon: HassioAddonInfo): string {
return addon.installed !== addon.version
? "hassio:arrow-up-bold-circle"
: "hassio:puzzle";
}
private _computeIconTitle(addon: HassioAddonInfo): string {
if (addon.installed !== addon.version) {
return "New version available";
}
return addon.state === "started"
? "Add-on is running"
: "Add-on is stopped";
}
private _computeIconClass(addon: HassioAddonInfo): string {
if (addon.installed !== addon.version) {
return "update";
}
return addon.state === "started" ? "running" : "";
}
private _addonTapped(ev: any): void { private _addonTapped(ev: any): void {
navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`); navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`);
} }

View File

@ -1,9 +1,12 @@
window.loadES5Adapter().then(() => { window.loadES5Adapter().then(() => {
// eslint-disable-next-line
import(/* webpackChunkName: "roboto" */ "../../src/resources/roboto");
// eslint-disable-next-line // eslint-disable-next-line
import(/* webpackChunkName: "hassio-icons" */ "./resources/hassio-icons"); import(/* webpackChunkName: "hassio-icons" */ "./resources/hassio-icons");
// eslint-disable-next-line // eslint-disable-next-line
import(/* webpackChunkName: "hassio-main" */ "./hassio-main"); import(/* webpackChunkName: "hassio-main" */ "./hassio-main");
}); });
const styleEl = document.createElement("style"); const styleEl = document.createElement("style");
styleEl.innerHTML = ` styleEl.innerHTML = `
body { body {

View File

@ -17,11 +17,11 @@ export const hassioStyle = css`
font-weight: var(--paper-font-headline_-_font-weight); font-weight: var(--paper-font-headline_-_font-weight);
letter-spacing: var(--paper-font-headline_-_letter-spacing); letter-spacing: var(--paper-font-headline_-_letter-spacing);
line-height: var(--paper-font-headline_-_line-height); line-height: var(--paper-font-headline_-_line-height);
padding-left: 16px; padding-left: 8px;
} }
.description { .description {
margin-top: 4px; margin-top: 4px;
padding-left: 16px; padding-left: 8px;
} }
.card-group { .card-group {
display: grid; display: grid;