ha-frontend/src/cards/ha-media_player-card.html

287 lines
6.7 KiB
HTML
Raw Normal View History

2016-04-10 10:31:28 +02:00
<link rel='import' href='../../bower_components/polymer/polymer.html'>
<link rel="import" href="../../bower_components/paper-material/paper-material.html">
<link rel='import' href='../../bower_components/paper-icon-button/paper-icon-button.html'>
<dom-module id='ha-media_player-card'>
<template>
2016-07-19 10:19:44 +02:00
<style include="paper-material iron-flex iron-flex-alignment iron-positioning">
:host {
display: block;
position: relative;
font-size: 0px;
border-radius: 2px;
overflow: hidden;
}
.banner {
position: relative;
background-position: center center;
background-image: url(/static/images/card_media_player_bg.png);
background-repeat: no-repeat;
background-color: var(--primary-color);
border-top-left-radius: 2px;
border-top-right-radius: 2px;
}
.banner:before {
display: block;
content: "";
width: 100%;
/* removed .25% from 16:9 ratio to fix YT black bars */
padding-top: 56%;
transition: padding-top .8s;
}
.banner.no-cover:before {
padding-top: 91px;
}
.banner > .cover {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
background-position: center center;
background-size: cover;
transition: opacity .8s;
opacity: 1;
}
.banner.is-off > .cover {
opacity: 0;
}
.banner > .caption {
@apply(--paper-font-caption);
position: absolute;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, var(--dark-secondary-opacity));
padding: 8px 16px;
text-transform: capitalize;
font-size: 14px;
font-weight: 500;
color: white;
transition: background-color .5s;
}
.banner.is-off > .caption {
background-color: initial;
}
.banner > .caption .title {
@apply(--paper-font-common-nowrap);
font-size: 1.2em;
margin: 8px 0 4px;
}
.controls {
@apply(--paper-font-body1);
padding: 8px;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
background-color: white;
}
.controls paper-icon-button {
width: 44px;
height: 44px;
}
paper-icon-button {
color: var(--primary-text-color);
}
paper-icon-button[disabled] {
color: var(--paper-grey-400);
}
paper-icon-button.primary {
width: 56px !important;
height: 56px !important;
background-color: var(--primary-color);
color: white;
border-radius: 50%;
padding: 8px;
transition: background-color .5s;
}
paper-icon-button.primary[disabled] {
background-color: rgba(0, 0, 0, var(--dark-disabled-opacity));
}
[invisible] {
visibility: hidden !important;
}
</style>
<div class$='[[computeBannerClasses(playerObj)]]'>
<div class='cover' id='cover'></div>
<div class='caption'>
[[stateObj.entityDisplay]]
<div class='title'>[[playerObj.primaryText]]</div>
[[playerObj.secondaryText]]<br />
</div>
</div>
2016-04-10 10:31:28 +02:00
<div class='controls layout horizontal justified'>
<paper-icon-button
icon='mdi:power'
on-tap='handleTogglePower'
invisible$='[[!playerObj.supportsTurnOff]]'
class='self-center secondary'
></paper-icon-button>
<div>
<paper-icon-button
icon='mdi:skip-previous'
invisible$='[[!playerObj.supportsPreviousTrack]]'
2016-04-12 09:50:53 +02:00
disabled='[[playerObj.isOff]]'
on-tap='handlePrevious'
></paper-icon-button>
2016-04-10 10:31:28 +02:00
<paper-icon-button
class='primary'
icon='[[computePlaybackControlIcon(playerObj)]]'
invisible='[[!computePlaybackControlIcon(playerObj)]]'
disabled='[[playerObj.isOff]]'
on-tap='handlePlaybackControl'
2016-04-10 10:31:28 +02:00
></paper-icon-button>
<paper-icon-button
icon='mdi:skip-next'
invisible$='[[!playerObj.supportsNextTrack]]'
2016-04-12 09:50:53 +02:00
disabled='[[playerObj.isOff]]'
on-tap='handleNext'
2016-04-10 10:31:28 +02:00
></paper-icon-button>
</div>
<paper-icon-button
icon='mdi:dots-vertical'
on-tap='handleOpenMoreInfo'
class='self-center secondary'
></paper-icon-button>
2016-04-10 10:31:28 +02:00
</div>
</template>
</dom-module>
2016-07-18 08:18:48 +02:00
<script>
Polymer({
is: 'ha-media_player-card',
properties: {
hass: {
type: Object,
},
stateObj: {
type: Object,
},
playerObj: {
type: Object,
computed: 'computePlayerObj(stateObj)',
observer: 'playerObjChanged',
},
playbackControlIcon: {
type: String,
computed: 'computePlaybackControlIcon(playerObj)',
},
/**
* The z-depth of the card, from 0-5.
*/
elevation: {
type: Number,
value: 1,
reflectToAttribute: true,
},
},
playerObjChanged: function (playerObj) {
if (!playerObj.isOff && !playerObj.isIdle) {
this.$.cover.style.backgroundImage = playerObj.stateObj.attributes.entity_picture ?
'url(' + playerObj.stateObj.attributes.entity_picture + ')' : '';
}
},
computeBannerClasses: function (playerObj) {
var cls = 'banner';
if (playerObj.isOff || playerObj.isIdle) {
cls += ' is-off';
}
if (!playerObj.stateObj.attributes.entity_picture) {
cls += ' no-cover';
}
return cls;
},
computeHidePowerOnButton: function (playerObj) {
return !playerObj.isOff || !playerObj.supportsTurnOn;
},
computePlayerObj: function (stateObj) {
return stateObj.domainModel(this.hass);
},
computePlaybackControlIcon: function (playerObj) {
if (playerObj.isPlaying) {
return playerObj.supportsPause ? 'mdi:pause' : 'mdi:stop';
} else if (playerObj.isPaused || playerObj.isOff) {
return 'mdi:play';
}
return '';
},
computeShowControls: function (playerObj) {
return !playerObj.isOff;
},
handleNext: function (ev) {
ev.stopPropagation();
this.playerObj.nextTrack();
},
handleOpenMoreInfo: function (ev) {
ev.stopPropagation();
this.async(function () {
this.hass.moreInfoActions.selectEntity(this.stateObj.entityId);
}, 1);
},
handlePlaybackControl: function (ev) {
ev.stopPropagation();
this.playerObj.mediaPlayPause();
},
handlePrevious: function (ev) {
ev.stopPropagation();
this.playerObj.previousTrack();
},
handleTogglePower: function (ev) {
ev.stopPropagation();
this.playerObj.togglePower();
},
});
</script>