diff --git a/src/components/ha-sidebar.ts b/src/components/ha-sidebar.ts index 575cb4cc2f..4f86c9f202 100644 --- a/src/components/ha-sidebar.ts +++ b/src/components/ha-sidebar.ts @@ -374,7 +374,11 @@ class HaSidebar extends LitElement { @mouseleave=${this._itemMouseLeave} > - + ${hass.user ? hass.user.name : ""} diff --git a/src/components/user/ha-user-badge.ts b/src/components/user/ha-user-badge.ts index 3e418ff596..c7fd114ae4 100644 --- a/src/components/user/ha-user-badge.ts +++ b/src/components/user/ha-user-badge.ts @@ -3,13 +3,16 @@ import { CSSResult, customElement, html, + internalProperty, LitElement, property, TemplateResult, } from "lit-element"; +import { styleMap } from "lit-html/directives/style-map"; import { toggleAttribute } from "../../common/dom/toggle_attribute"; +import { computeStateDomain } from "../../common/entity/compute_state_domain"; import { User } from "../../data/user"; -import { CurrentUser } from "../../types"; +import { CurrentUser, HomeAssistant } from "../../types"; const computeInitials = (name: string) => { if (!name) { @@ -29,26 +32,93 @@ const computeInitials = (name: string) => { @customElement("ha-user-badge") class StateBadge extends LitElement { - @property() public user?: User | CurrentUser; + @property({ attribute: false }) public hass!: HomeAssistant; - protected render(): TemplateResult { - const user = this.user; - const initials = user ? computeInitials(user.name) : "?"; - return html` ${initials} `; - } + @property({ attribute: false }) public user?: User | CurrentUser; + + @internalProperty() private _personPicture?: string; + + private _personEntityId?: string; protected updated(changedProps) { super.updated(changedProps); - toggleAttribute( - this, - "long", - (this.user ? computeInitials(this.user.name) : "?").length > 2 - ); + if (changedProps.has("user")) { + this._getPersonPicture(); + if (!this._personPicture) { + toggleAttribute( + this, + "long", + (this.hass.user ? computeInitials(this.hass.user.name) : "?").length > + 2 + ); + } + return; + } + const oldHass = changedProps.get("hass"); + if ( + this._personEntityId && + oldHass && + this.hass.states[this._personEntityId] !== + oldHass.states[this._personEntityId] + ) { + const state = this.hass.states[this._personEntityId]; + if (state) { + this._personPicture = state.attributes.entity_picture; + } else { + this._getPersonPicture(); + } + } + } + + protected render(): TemplateResult { + if (!this.hass || !this.user) { + return html``; + } + const user = this.user; + const picture = this._personPicture; + + return html` + ${picture + ? html`
` + : html`
2} + > + ${computeInitials(user?.name!)} +
`} + `; + } + + private _getPersonPicture() { + this._personEntityId = undefined; + this._personPicture = undefined; + if (!this.hass || !this.user) { + return; + } + for (const entity of Object.values(this.hass.states)) { + if ( + entity.attributes.user_id === this.user!.id && + computeStateDomain(entity) === "person" + ) { + this._personEntityId = entity.entity_id; + this._personPicture = entity.attributes.entity_picture; + break; + } + } } static get styles(): CSSResult { return css` - :host { + .picture { + width: 40px; + height: 40px; + background-size: cover; + border-radius: 50%; + } + .initials { display: inline-block; box-sizing: border-box; width: 40px; @@ -60,8 +130,7 @@ class StateBadge extends LitElement { color: var(--text-light-primary-color, var(--primary-text-color)); overflow: hidden; } - - :host([long]) { + :host([long]) .initials { font-size: 80%; } `; diff --git a/src/components/user/ha-user-picker.ts b/src/components/user/ha-user-picker.ts index d9a7fda1ec..ecd99f188f 100644 --- a/src/components/user/ha-user-picker.ts +++ b/src/components/user/ha-user-picker.ts @@ -53,7 +53,11 @@ class HaUserPicker extends LitElement { ${this._sortedUsers(this.users).map( (user) => html` - + ${user.name} ` diff --git a/src/panels/config/person/ha-config-person.ts b/src/panels/config/person/ha-config-person.ts index 764ae63b28..24f794b4e8 100644 --- a/src/panels/config/person/ha-config-person.ts +++ b/src/panels/config/person/ha-config-person.ts @@ -1,17 +1,21 @@ +import "@material/mwc-fab"; +import { mdiPlus } from "@mdi/js"; import "@polymer/paper-item/paper-icon-item"; import "@polymer/paper-item/paper-item-body"; import { css, CSSResult, html, + internalProperty, LitElement, property, - internalProperty, TemplateResult, } from "lit-element"; +import { styleMap } from "lit-html/directives/style-map"; import { compare } from "../../../common/string/compare"; import "../../../components/ha-card"; -import "@material/mwc-fab"; +import "../../../components/ha-svg-icon"; +import "../../../components/user/ha-user-badge"; import { createPerson, deletePerson, @@ -30,9 +34,6 @@ import { loadPersonDetailDialog, showPersonDetailDialog, } from "./show-dialog-person-detail"; -import "../../../components/ha-svg-icon"; -import { mdiPlus } from "@mdi/js"; -import { styleMap } from "lit-html/directives/style-map"; class HaConfigPerson extends LitElement { @property({ attribute: false }) public hass?: HomeAssistant;