diff --git a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.js b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.js deleted file mode 100644 index c123618852..0000000000 --- a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.js +++ /dev/null @@ -1,165 +0,0 @@ -import "@polymer/paper-icon-button/paper-icon-button"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import "../components/hui-generic-entity-row"; - -import LocalizeMixin from "../../../mixins/localize-mixin"; - -const SUPPORT_PAUSE = 1; -const SUPPORT_NEXT_TRACK = 32; -const SUPPORTS_PLAY = 16384; -const OFF_STATES = ["off", "idle"]; - -/* - * @appliesMixin LocalizeMixin - */ -class HuiMediaPlayerEntityRow extends LocalizeMixin(PolymerElement) { - static get template() { - return html` - ${this.styleTemplate} - - ${this.mediaPlayerControlTemplate} - - `; - } - - static get styleTemplate() { - return html` - - `; - } - - static get mediaPlayerControlTemplate() { - return html` - - - -
[[_computeMediaTitle(_stateObj)]]
- `; - } - - static get properties() { - return { - hass: Object, - _config: Object, - _stateObj: { - type: Object, - computed: "_computeStateObj(hass.states, _config.entity)", - }, - }; - } - - _computeStateObj(states, entityId) { - return states && entityId in states ? states[entityId] : null; - } - - setConfig(config) { - if (!config || !config.entity) { - throw new Error("Entity not configured."); - } - this._config = config; - } - - _computeControlIcon(stateObj) { - if (!stateObj) return null; - - if (stateObj.state !== "playing") { - return stateObj.attributes.supported_features & SUPPORTS_PLAY - ? "hass:play" - : ""; - } - - return stateObj.attributes.supported_features & SUPPORT_PAUSE - ? "hass:pause" - : "hass:stop"; - } - - _computeMediaTitle(stateObj) { - if (!stateObj || this._isOff(stateObj.state)) return null; - - let prefix; - let suffix; - - switch (stateObj.attributes.media_content_type) { - case "music": - prefix = stateObj.attributes.media_artist; - suffix = stateObj.attributes.media_title; - break; - case "tvshow": - prefix = stateObj.attributes.media_series_title; - suffix = stateObj.attributes.media_title; - break; - default: - prefix = - stateObj.attributes.media_title || - stateObj.attributes.app_name || - stateObj.state; - suffix = ""; - } - - return prefix && suffix ? `${prefix}: ${suffix}` : prefix || suffix || ""; - } - - _computeState(state) { - return ( - this.localize(`state.media_player.${state}`) || - this.localize(`state.default.${state}`) || - state - ); - } - - _callService(service) { - this.hass.callService("media_player", service, { - entity_id: this._config.entity, - }); - } - - _playPause(event) { - event.stopPropagation(); - this._callService("media_play_pause"); - } - - _nextTrack(event) { - event.stopPropagation(); - if (this._stateObj.attributes.supported_features & SUPPORT_NEXT_TRACK) { - this._callService("media_next_track"); - } - } - - _isOff(state) { - return OFF_STATES.includes(state); - } - - _supportsNext(stateObj) { - return ( - stateObj && stateObj.attributes.supported_features & SUPPORT_NEXT_TRACK - ); - } -} -customElements.define("hui-media-player-entity-row", HuiMediaPlayerEntityRow); diff --git a/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts new file mode 100644 index 0000000000..10c3860b67 --- /dev/null +++ b/src/panels/lovelace/entity-rows/hui-media-player-entity-row.ts @@ -0,0 +1,171 @@ +import { html, LitElement } from "@polymer/lit-element"; +import { TemplateResult } from "lit-html"; +import "@polymer/paper-icon-button/paper-icon-button"; + +import "../components/hui-generic-entity-row"; + +import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin"; +import { EntityRow, EntityConfig } from "./types"; +import { HomeAssistant } from "../../../types"; +import { HassEntity } from "home-assistant-js-websocket"; + +const SUPPORT_PAUSE = 1; +const SUPPORT_NEXT_TRACK = 32; +const SUPPORTS_PLAY = 16384; +const OFF_STATES = ["off", "idle"]; + +class HuiMediaPlayerEntityRow extends hassLocalizeLitMixin(LitElement) + implements EntityRow { + public hass?: HomeAssistant; + private _config?: EntityConfig; + + static get properties() { + return { + hass: {}, + _config: {}, + }; + } + + public setConfig(config: EntityConfig): void { + if (!config || !config.entity) { + throw new Error("Invalid Configuration: 'entity' required"); + } + + this._config = config; + } + + protected render(): TemplateResult { + if (!this.hass || !this._config) { + return html``; + } + + const stateObj = this.hass.states[this._config.entity]; + + if (!stateObj) { + return html` + + `; + } + + const supportsPlay = + // tslint:disable-next-line:no-bitwise + stateObj.attributes.supported_features! & SUPPORTS_PLAY; + const supportsNext = + // tslint:disable-next-line:no-bitwise + stateObj.attributes.supported_features! & SUPPORT_NEXT_TRACK; + + return html` + ${this.renderStyle()} + + ${ + OFF_STATES.includes(stateObj.state) + ? html` +
+ ${ + this.localize(`state.media_player.${stateObj.state}`) || + this.localize(`state.default.${stateObj.state}`) || + stateObj.state + } +
+ ` + : html` +
+ ${ + stateObj.state !== "playing" && !supportsPlay + ? "" + : html` + + ` + } + ${ + supportsNext + ? html` + + ` + : "" + } +
+
${this._computeMediaTitle(stateObj)}
+ ` + } +
+ `; + } + + private renderStyle(): TemplateResult { + return html` + + `; + } + + private _computeControlIcon(stateObj: HassEntity): string { + if (stateObj.state !== "playing") { + return "hass:play"; + } + + // tslint:disable-next-line:no-bitwise + return stateObj.attributes.supported_features! & SUPPORT_PAUSE + ? "hass:pause" + : "hass:stop"; + } + + private _computeMediaTitle(stateObj: HassEntity): string { + let prefix; + let suffix; + + switch (stateObj.attributes.media_content_type) { + case "music": + prefix = stateObj.attributes.media_artist; + suffix = stateObj.attributes.media_title; + break; + case "tvshow": + prefix = stateObj.attributes.media_series_title; + suffix = stateObj.attributes.media_title; + break; + default: + prefix = + stateObj.attributes.media_title || + stateObj.attributes.app_name || + stateObj.state; + suffix = ""; + } + + return prefix && suffix ? `${prefix}: ${suffix}` : prefix || suffix || ""; + } + + private _playPause(): void { + this.hass!.callService("media_player", "media_play_pause", { + entity_id: this._config!.entity, + }); + } + + private _nextTrack(): void { + this.hass!.callService("media_player", "media_next_track", { + entity_id: this._config!.entity, + }); + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-media-player-entity-row": HuiMediaPlayerEntityRow; + } +} + +customElements.define("hui-media-player-entity-row", HuiMediaPlayerEntityRow);