Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add entity picture support to entity card #393

Merged
merged 2 commits into from
Apr 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 14 additions & 13 deletions docs/cards/entity.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,17 @@ A entity card allow you to display an entity.

All the options are available in the lovelace editor but you can use `yaml` if you want.

| Name | Type | Default | Description |
| :------------------ | :-------------------------------------------------- | :---------- | :------------------------------------------------------------------------ |
| `entity` | string | Required | Entity |
| `icon` | string | Optional | Custom icon |
| `icon_color` | string | `blue` | Custom color for icon when entity is state is active |
| `hide_icon` | boolean | `false` | Hide the entity icon |
| `name` | string | Optional | Custom name |
| `layout` | string | Optional | Layout of the card. Vertical, horizontal and default layout are supported |
| `primary_info` | `name` `state` `last-changed` `last-updated` `none` | `name` | Info to show as primary info |
| `secondary_info` | `name` `state` `last-changed` `last-updated` `none` | `state` | Info to show as secondary info |
| `tap_action` | action | `more-info` | Home assistant action to perform on tap |
| `hold_action` | action | `more-info` | Home assistant action to perform on hold |
| `double_tap_action` | action | `more-info` | Home assistant action to perform on double_tap |
| Name | Type | Default | Description |
| :------------------- | :-------------------------------------------------- | :---------- | :------------------------------------------------------------------------ |
| `entity` | string | Required | Entity |
| `icon` | string | Optional | Custom icon |
| `icon_color` | string | `blue` | Custom color for icon when entity is state is active |
| `hide_icon` | boolean | `false` | Hide the entity icon |
| `use_entity_picture` | boolean | `false` | Use the picture of the entity instead of icon |
| `name` | string | Optional | Custom name |
| `layout` | string | Optional | Layout of the card. Vertical, horizontal and default layout are supported |
| `primary_info` | `name` `state` `last-changed` `last-updated` `none` | `name` | Info to show as primary info |
| `secondary_info` | `name` `state` `last-changed` `last-updated` `none` | `state` | Info to show as secondary info |
| `tap_action` | action | `more-info` | Home assistant action to perform on tap |
| `hold_action` | action | `more-info` | Home assistant action to perform on hold |
| `double_tap_action` | action | `more-info` | Home assistant action to perform on double_tap |
39 changes: 18 additions & 21 deletions src/cards/chips-card/chips/entity-chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ export class EntityChip extends LitElement implements LovelaceChip {
const name = this._config.name || entity.attributes.friendly_name || "";
const icon = this._config.icon || stateIcon(entity);
const iconColor = this._config.icon_color;

const picture = this._config.use_entity_picture
? entity.attributes.entity_picture
: undefined;
Expand Down Expand Up @@ -94,28 +95,29 @@ export class EntityChip extends LitElement implements LovelaceChip {
hasHold: hasAction(this._config.hold_action),
hasDoubleClick: hasAction(this._config.double_tap_action),
})}
avatar=${picture}
>
${ picture ?
html`
<img
src="${picture}"
class="mushroom-chip-entity-picture"
/>
`
:
html`
<ha-icon
.icon=${icon}
style=${styleMap(iconStyle)}
class=${classMap({ active })}
></ha-icon>
`
}
${!picture ? this.renderIcon(icon, iconColor, active) : null}
${content ? html`<span>${content}</span>` : null}
</mushroom-chip>
`;
}

renderIcon(icon: string, iconColor: string | undefined, active: boolean): TemplateResult {
const iconStyle = {};
if (iconColor) {
const iconRgbColor = computeRgbColor(iconColor);
iconStyle["--color"] = `rgb(${iconRgbColor})`;
}
return html`
<ha-icon
.icon=${icon}
style=${styleMap(iconStyle)}
class=${classMap({ active })}
></ha-icon>
`;
}

static get styles(): CSSResultGroup {
return css`
mushroom-chip {
Expand All @@ -124,11 +126,6 @@ export class EntityChip extends LitElement implements LovelaceChip {
ha-icon.active {
color: var(--color);
}
.mushroom-chip-entity-picture {
border-radius: var(--chip-entity-picture-border-radius);
height: var(--chip-entity-picture-size);
width: var(--chip-entity-picture-size);
}
`;
}
}
2 changes: 2 additions & 0 deletions src/cards/entity-card/entity-card-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface EntityCardConfig extends LovelaceCardConfig {
icon?: string;
name?: string;
icon_color?: string;
use_entity_picture?: boolean;
hide_icon?: boolean;
layout?: Layout;
primary_info?: Info;
Expand All @@ -26,6 +27,7 @@ export const entityCardConfigStruct = assign(
icon: optional(string()),
name: optional(string()),
icon_color: optional(string()),
use_entity_picture: optional(boolean()),
hide_icon: optional(boolean()),
layout: optional(layoutStruct),
primary_info: optional(enums(INFOS)),
Expand Down
1 change: 1 addition & 0 deletions src/cards/entity-card/entity-card-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const computeSchema = memoizeOne((icon?: string): HaFormSchema[] => [
schema: [
{ name: "layout", selector: { "mush-layout": {} } },
{ name: "hide_icon", selector: { boolean: {} } },
{ name: "use_entity_picture", selector: { boolean: {} } },
],
},
{
Expand Down
14 changes: 13 additions & 1 deletion src/cards/entity-card/entity-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { computeStateDisplay } from "../../ha/common/entity/compute-state-displa
import { isActive, isAvailable } from "../../ha/data/entity";
import "../../shared/badge-icon";
import "../../shared/card";
import "../../shared/shape-avatar";
import "../../shared/shape-icon";
import "../../shared/state-info";
import "../../shared/state-item";
Expand Down Expand Up @@ -88,6 +89,10 @@ export class EntityCard extends LitElement implements LovelaceCard {
const hideIcon = !!this._config.hide_icon;
const layout = getLayoutFromConfig(this._config);

const picture = this._config.use_entity_picture
? entity.attributes.entity_picture
: undefined;

const stateDisplay = computeStateDisplay(this.hass.localize, entity, this.hass.locale);

const primary = getInfo(
Expand Down Expand Up @@ -122,7 +127,14 @@ export class EntityCard extends LitElement implements LovelaceCard {
.hide_info=${primary == null && secondary == null}
.hide_icon=${hideIcon}
>
${!hideIcon ? this.renderIcon(icon, iconColor, isActive(entity)) : undefined}
${picture
? html`
<mushroom-shape-avatar
slot="icon"
.picture_url=${picture}
></mushroom-shape-avatar>
`
: this.renderIcon(icon, iconColor, isActive(entity))}
${!isAvailable(entity)
? html`
<mushroom-badge-icon
Expand Down
30 changes: 27 additions & 3 deletions src/shared/chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ export class BadgeIcon extends LitElement {

@property() public label: string = "";

@property() public avatar: string = "";

protected render(): TemplateResult {
return html`
<ha-card class="chip">
<slot></slot>
${this.avatar ? html` <img class="avatar" src=${this.avatar} /> ` : null}
<div class="content">
<slot></slot>
</div>
</ha-card>
`;
}
Expand All @@ -25,14 +30,33 @@ export class BadgeIcon extends LitElement {
.chip {
box-sizing: border-box;
height: var(--chip-height);
font-size: calc(var(--chip-height) * 0.3);
width: auto;
padding: var(--chip-padding);
border-radius: var(--chip-border-radius);
display: flex;
flex-direction: row;
align-items: center;
}
.avatar {
--avatar-size: calc(var(--chip-height) - 2 * var(--chip-avatar-padding));
border-radius: var(--chip-avatar-border-radius);
height: var(--avatar-size);
width: var(--avatar-size);
margin-left: var(--chip-avatar-padding);
box-sizing: border-box;
object-fit: cover;
}
:host([rtl]) .avatar {
margin-left: initial;
margin-right: var(--chip-avatar-padding);
}
.content {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
height: 100%;
font-size: calc(var(--chip-height) * 0.3);
padding: var(--chip-padding);
line-height: 0;
}
::slotted(ha-icon) {
Expand Down
4 changes: 2 additions & 2 deletions src/utils/card-styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ export const cardStyle = css`
--chip-font-size: var(--mush-chip-font-size, 1em);
--chip-font-weight: var(--mush-chip-font-weight, bold);
--chip-icon-size: var(--mush-chip-icon-size, 1.5em);
--chip-entity-picture-border-radius: var(--mush-chip-entity-picture-border-radius, 50%);
--chip-entity-picture-size: var(--mush-chip-entity-picture-size, 24px);
--chip-avatar-padding: var(--mush-chip-avatar-padding, 0.3em);
--chip-avatar-border-radius: var(--mush-chip-avatar-border-radius, 50%);
/* Slider */
--slider-threshold: var(--mush-slider-threshold);
}
Expand Down