Style unavailable/unknown cards (#5104)

* Style unavailable/unknown cards

* Hide default image if unavailable

* Style map

Co-authored-by: Zack Arnett <arnett.zackary@gmail.com>
This commit is contained in:
Paulus Schoutsen 2020-03-08 14:19:58 -07:00 committed by GitHub
parent 814fcf63a8
commit 64ee7456dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -27,7 +27,7 @@ import { hasConfigOrEntityChanged } from "../common/has-changed";
import { contrast } from "../common/color/contrast"; import { contrast } from "../common/color/contrast";
import { findEntities } from "../common/find-entites"; import { findEntities } from "../common/find-entites";
import { LovelaceConfig } from "../../../data/lovelace"; import { LovelaceConfig } from "../../../data/lovelace";
import { UNAVAILABLE } from "../../../data/entity"; import { UNAVAILABLE, UNKNOWN } from "../../../data/entity";
import { import {
OFF_STATES, OFF_STATES,
SUPPORT_PAUSE, SUPPORT_PAUSE,
@ -165,24 +165,32 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
width: `${this._cardHeight}px`, width: `${this._cardHeight}px`,
}; };
const isOffState = OFF_STATES.includes(stateObj.state);
const isUnavailable =
stateObj.state === UNAVAILABLE ||
stateObj.state === UNKNOWN ||
(stateObj.state === "off" && !supportsFeature(stateObj, SUPPORT_TURN_ON));
const hasNoImage = !this._image;
return html` return html`
<ha-card> <ha-card>
<div <div
class="background ${classMap({ class="background ${classMap({
"no-image": !this._image, "no-image": hasNoImage,
off: OFF_STATES.includes(stateObj.state), off: isOffState || isUnavailable,
unavailable: isUnavailable,
})}" })}"
> >
<div <div
class="color-block" class="color-block"
style="background-color: ${this._backgroundColor}" style=${styleMap({ "background-color": this._backgroundColor! })}
></div> ></div>
<div <div
class="no-img" class="no-img"
style="background-color: ${this._backgroundColor}" style=${styleMap({ "background-color": this._backgroundColor! })}
></div> ></div>
<div class="image" style=${styleMap(imageStyle)}></div> <div class="image" style=${styleMap(imageStyle)}></div>
${!this._image ${hasNoImage
? "" ? ""
: html` : html`
<div <div
@ -193,12 +201,12 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
</div> </div>
<div <div
class="player ${classMap({ class="player ${classMap({
"no-image": !this._image, "no-image": hasNoImage,
narrow: this._narrow && !this._veryNarrow, narrow: this._narrow && !this._veryNarrow,
off: OFF_STATES.includes(stateObj.state), off: isOffState || isUnavailable,
"no-progress": !this._showProgressBar && !this._veryNarrow, "no-progress": !this._showProgressBar && !this._veryNarrow,
})}" })}"
style="color: ${this._foregroundColor}" style=${styleMap({ color: this._foregroundColor! })}
> >
<div class="top-info"> <div class="top-info">
<div class="icon-name"> <div class="icon-name">
@ -216,101 +224,120 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
></paper-icon-button> ></paper-icon-button>
</div> </div>
</div> </div>
<div ${isUnavailable
class="title-controls" ? ""
style="padding-right: ${OFF_STATES.includes(stateObj.state) : html`
? 0 <div
: this._cardHeight - 40}px" class="title-controls"
> style=${styleMap({
${OFF_STATES.includes(stateObj.state) paddingRight: isOffState
? "" ? "0"
: html` : `${this._cardHeight - 40}px`,
<div class="media-info"> })}
<div class="title"> >
${stateObj.attributes.media_title || ${isOffState
computeMediaDescription(stateObj)} ? ""
</div> : html`
${!stateObj.attributes.media_title <div class="media-info">
? "" <div class="title">
: computeMediaDescription(stateObj)} ${stateObj.attributes.media_title ||
</div> computeMediaDescription(stateObj)}
`} </div>
${this._veryNarrow && !OFF_STATES.includes(stateObj.state) ${!stateObj.attributes.media_title
? "" ? ""
: html` : computeMediaDescription(stateObj)}
<div class="controls"> </div>
<div> `}
${(stateObj.state === "off" && ${this._veryNarrow && !isOffState
!supportsFeature(stateObj, SUPPORT_TURN_ON)) || ? ""
!OFF_STATES.includes(stateObj.state) : html`
? "" <div class="controls">
: html` <div>
<paper-icon-button ${(stateObj.state === "off" &&
icon="hass:power" !supportsFeature(stateObj, SUPPORT_TURN_ON)) ||
.action=${stateObj.state === "off" !isOffState
? "turn_on"
: "turn_off"}
@click=${this._handleClick}
></paper-icon-button>
`}
</div>
${OFF_STATES.includes(stateObj.state)
? ""
: html`
<div class="playback-controls">
${!supportsFeature(stateObj, SUPPORT_PREVIOUS_TRACK)
? "" ? ""
: html` : html`
<paper-icon-button <paper-icon-button
icon="hass:skip-previous" icon="hass:power"
.action=${"media_previous_track"} .action=${stateObj.state === "off"
@click=${this._handleClick} ? "turn_on"
></paper-icon-button> : "turn_off"}
`}
${(stateObj.state !== "playing" &&
!supportsFeature(stateObj, SUPPORTS_PLAY)) ||
stateObj.state === UNAVAILABLE ||
(stateObj.state === "playing" &&
!supportsFeature(stateObj, SUPPORT_PAUSE) &&
!supportsFeature(stateObj, SUPPORT_STOP))
? ""
: html`
<paper-icon-button
class="playPauseButton"
.icon=${stateObj.state !== "playing"
? "hass:play"
: supportsFeature(stateObj, SUPPORT_PAUSE)
? "hass:pause"
: "hass:stop"}
.action=${"media_play_pause"}
@click=${this._handleClick}
></paper-icon-button>
`}
${!supportsFeature(stateObj, SUPPORT_NEXT_TRACK)
? ""
: html`
<paper-icon-button
icon="hass:skip-next"
.action=${"media_next_track"}
@click=${this._handleClick} @click=${this._handleClick}
></paper-icon-button> ></paper-icon-button>
`} `}
</div> </div>
`} ${isOffState
</div> ? ""
`} : html`
</div> <div class="playback-controls">
${!this._showProgressBar ${!supportsFeature(
? "" stateObj,
: html` SUPPORT_PREVIOUS_TRACK
<paper-progress )
.max="${stateObj.attributes.media_duration}" ? ""
.value="${getCurrentProgress(stateObj)}" : html`
class="progress" <paper-icon-button
style="--paper-progress-active-color: ${this icon="hass:skip-previous"
._foregroundColor || "var(--accent-color)"}" .action=${"media_previous_track"}
@click=${(e: MouseEvent) => this._handleSeek(e, stateObj)} @click=${this._handleClick}
></paper-progress> ></paper-icon-button>
`}
${(stateObj.state !== "playing" &&
!supportsFeature(
stateObj,
SUPPORTS_PLAY
)) ||
stateObj.state === UNAVAILABLE ||
(stateObj.state === "playing" &&
!supportsFeature(stateObj, SUPPORT_PAUSE) &&
!supportsFeature(stateObj, SUPPORT_STOP))
? ""
: html`
<paper-icon-button
class="playPauseButton"
.icon=${stateObj.state !== "playing"
? "hass:play"
: supportsFeature(
stateObj,
SUPPORT_PAUSE
)
? "hass:pause"
: "hass:stop"}
.action=${"media_play_pause"}
@click=${this._handleClick}
></paper-icon-button>
`}
${!supportsFeature(
stateObj,
SUPPORT_NEXT_TRACK
)
? ""
: html`
<paper-icon-button
icon="hass:skip-next"
.action=${"media_next_track"}
@click=${this._handleClick}
></paper-icon-button>
`}
</div>
`}
</div>
`}
</div>
${!this._showProgressBar
? ""
: html`
<paper-progress
.max="${stateObj.attributes.media_duration}"
.value="${getCurrentProgress(stateObj)}"
class="progress"
style="--paper-progress-active-color: ${this
._foregroundColor || "var(--accent-color)"}"
@click=${(e: MouseEvent) =>
this._handleSeek(e, stateObj)}
></paper-progress>
`}
`} `}
</div> </div>
</ha-card> </ha-card>
@ -584,6 +611,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
width: 0; width: 0;
} }
.unavailable .no-img,
.background:not(.off):not(.no-image) .no-img { .background:not(.off):not(.no-image) .no-img {
opacity: 0; opacity: 0;
} }
@ -687,7 +715,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
.off.player, .off.player,
.narrow.player { .narrow.player {
padding-bottom: 8px !important; padding-bottom: 16px !important;
} }
.narrow .controls, .narrow .controls,