added browser-player card

This commit is contained in:
Thomas Lovén 2019-06-27 12:26:39 +02:00
parent 3e704e97d1
commit 4149759dd1
4 changed files with 173 additions and 3 deletions

View File

@ -1 +1,56 @@
!function(e){var t={};function n(o){if(t[o])return t[o].exports;var r=t[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,n),r.l=!0,r.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var r in e)n.d(o,r,function(t){return e[t]}.bind(null,r));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);let o=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${e()}${e()}-${e()}${e()}`}return localStorage["lovelace-player-device-id"]}();window.browser_mod=new class{constructor(){window.hassConnection.then(e=>this.connect(e.conn)),this.player=new Audio,this.player.addEventListener("ended",this.update.bind(this)),this.player.addEventListener("play",this.update.bind(this)),this.player.addEventListener("pause",this.update.bind(this)),this.player.addEventListener("volumechange",this.update.bind(this))}connect(e){console.log("Connection opened. Connecting to browser_mod"),this.conn=e,e.subscribeMessage(e=>this.callback(e),{type:"browser_mod/connect",deviceID:o}),console.log("Connected"),console.log(this.connection)}callback(e){switch(console.log("Got ws message"),console.log(e),e.command){case"update":this.update(e);break;case"play":this.play(e);break;case"pause":this.pause(e);break;case"stop":this.stop(e);break;case"set_volume":this.set_volume(e);break;case"mute":this.mute(e)}}get player_state(){return this.player.src?this.player.ended?"stopped":this.player.paused?"paused":"playing":"stopped"}play(e){const t=e.media_content_id;t&&(this.player.src=t),this.player.play()}pause(e){this.player.pause()}stop(e){this.player.pause(),this.player.src=null}set_volume(e){void 0!==e.volume_level&&(this.player.volume=e.volume_level)}mute(e){this.player.muted=Boolean(e.mute)}update(){this.conn&&this.conn.sendMessage({type:"browser_mod/update",deviceID:o,data:{browser:{},player:{volume:this.player.volume,muted:this.player.muted,src:this.player.src,state:this.player_state}}})}}}]); !function(e){var t={};function o(n){if(t[n])return t[n].exports;var a=t[n]={i:n,l:!1,exports:{}};return e[n].call(a.exports,a,a.exports,o),a.l=!0,a.exports}o.m=e,o.c=t,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var a in e)o.d(n,a,function(t){return e[t]}.bind(null,a));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=0)}([function(e,t,o){"use strict";o.r(t);let n=function(){if(window.fully&&"function"==typeof fully.getDeviceId)return fully.getDeviceId();if(!localStorage["lovelace-player-device-id"]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);localStorage["lovelace-player-device-id"]=`${e()}${e()}-${e()}${e()}`}return localStorage["lovelace-player-device-id"]}();const a=Object.getPrototypeOf(customElements.get("home-assistant-main")),s=a.prototype.html,r=a.prototype.css;function l(e,t=!1){!function(e,t,o=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},o)o.dispatchEvent(e);else{var n=document.querySelector("home-assistant");(n=(n=(n=(n=(n=(n=(n=(n=(n=(n=(n=n&&n.shadowRoot)&&n.querySelector("home-assistant-main"))&&n.shadowRoot)&&n.querySelector("app-drawer-layout partial-panel-resolver"))&&n.shadowRoot||n)&&n.querySelector("ha-panel-lovelace"))&&n.shadowRoot)&&n.querySelector("hui-root"))&&n.shadowRoot)&&n.querySelector("ha-app-layout #view"))&&n.firstElementChild)&&n.dispatchEvent(e)}}("hass-more-info",{entityId:e},document.querySelector("home-assistant"));const o=document.querySelector("home-assistant")._moreInfoEl;return o.large=t,o}customElements.define("browser-player",class extends a{static get properties(){return{hass:{}}}setConfig(e){this._config=e}handleMute(e){window.browser_mod.mute({})}handleVolumeChange(e){const t=parseFloat(e.target.value);window.browser_mod.set_volume({volume_level:t})}handleMoreInfo(e){l(window.browser_mod.entity_id)}handlePlayPause(e){window.browser_mod.player.paused?window.browser_mod.play({}):window.browser_mod.pause({})}render(){const e=window.browser_mod.player;return s`
<ha-card>
<div class="card-content">
<paper-icon-button
.icon=${e.muted?"mdi:volume-off":"mdi:volume-high"}
@click=${this.handleMute}
></paper-icon-button>
<ha-paper-slider
min=0
max=1
step=0.01
?disabled=${e.muted}
value=${e.volume}
@change=${this.handleVolumeChange}
></ha-paper-slider>
${"stopped"===window.browser_mod.player_state?s`<div class="placeholder"></div>`:s`
<paper-icon-button
.icon=${e.paused?"mdi:play":"mdi:pause"}
@click=${this.handlePlayPause}
highlight
></paper-icon-button>
`}
<paper-icon-button
.icon=${"mdi:settings"}
@click=${this.handleMoreInfo}
></paper-icon-button>
</div>
<div class="device-id">
${n}
</div>
</ha-card>
`}static get styles(){return r`
paper-icon-button[highlight] {
color: var(--accent-color);
}
.card-content {
display: flex;
justify-content: center;
}
.placeholder {
width: 24px;
padding: 8px;
}
.device-id {
opacity: 0.7;
font-size: xx-small;
margin-top: -10px;
user-select: all;
-webkit-user-select: all;
-moz-user-select: all;
-ms-user-select: all;
}
`}});window.browser_mod=new class{constructor(){window.hassConnection.then(e=>this.connect(e.conn)),this.player=new Audio,this.player.addEventListener("ended",this.update.bind(this)),this.player.addEventListener("play",this.update.bind(this)),this.player.addEventListener("pause",this.update.bind(this)),this.player.addEventListener("volumechange",this.update.bind(this))}connect(e){console.log("Connection opened. Connecting to browser_mod"),this.conn=e,e.subscribeMessage(e=>this.callback(e),{type:"browser_mod/connect",deviceID:n}),console.log("Connected"),console.log(this.connection)}callback(e){switch(console.log("Got ws message"),console.log(e),e.command){case"update":this.update(e);break;case"play":this.play(e);break;case"pause":this.pause(e);break;case"stop":this.stop(e);break;case"set_volume":this.set_volume(e);break;case"mute":this.mute(e)}}get player_state(){return this.player.src?this.player.ended?"stopped":this.player.paused?"paused":"playing":"stopped"}play(e){const t=e.media_content_id;t&&(this.player.src=t),this.player.play()}pause(e){this.player.pause()}stop(e){this.player.pause(),this.player.src=null}set_volume(e){void 0!==e.volume_level&&(this.player.volume=e.volume_level)}mute(e){void 0===e.mute&&(e.mute=!this.player.muted),this.player.muted=Boolean(e.mute)}update(e=null){this.conn&&(e&&e.entity_id&&(this.entity_id=e.entity_id),this.conn.sendMessage({type:"browser_mod/update",deviceID:n,data:{browser:{},player:{volume:this.player.volume,muted:this.player.muted,src:this.player.src,state:this.player_state}}}))}}}]);

View File

@ -62,7 +62,7 @@ class BrowserModEntity(Entity):
self._ws_cid = cid self._ws_cid = cid
self._ws_connection = connection self._ws_connection = connection
_LOGGER.error(f"Connecting {self.entity_id}") _LOGGER.error(f"Connecting {self.entity_id}")
self.ws_send("update") self.ws_send("update", entity_id=self.entity_id)
connection.subscriptions[cid] = self.ws_disconnect connection.subscriptions[cid] = self.ws_disconnect
if self.hass: if self.hass:
self.schedule_update_ha_state() self.schedule_update_ha_state()

107
js/browser-player.js Normal file
View File

@ -0,0 +1,107 @@
import { LitElement, html, css } from "/card-tools/lit-element";
import { deviceID } from "/card-tools/deviceId"
import { moreInfo } from "/card-tools/more-info"
class BrowserPlayer extends LitElement {
static get properties() {
return {
hass: {},
};
}
setConfig(config) {
this._config = config;
}
handleMute(ev) {
window.browser_mod.mute({});
}
handleVolumeChange(ev) {
const vol = parseFloat(ev.target.value);
window.browser_mod.set_volume({volume_level: vol});
}
handleMoreInfo(ev) {
moreInfo(window.browser_mod.entity_id);
}
handlePlayPause(ev) {
if (window.browser_mod.player.paused)
window.browser_mod.play({});
else
window.browser_mod.pause({});
}
render() {
const player = window.browser_mod.player;
return html`
<ha-card>
<div class="card-content">
<paper-icon-button
.icon=${player.muted
? "mdi:volume-off"
: "mdi:volume-high"
}
@click=${this.handleMute}
></paper-icon-button>
<ha-paper-slider
min=0
max=1
step=0.01
?disabled=${player.muted}
value=${player.volume}
@change=${this.handleVolumeChange}
></ha-paper-slider>
${window.browser_mod.player_state === "stopped"
? html`<div class="placeholder"></div>`
: html`
<paper-icon-button
.icon=${player.paused
? "mdi:play"
: "mdi:pause"
}
@click=${this.handlePlayPause}
highlight
></paper-icon-button>
`}
<paper-icon-button
.icon=${"mdi:settings"}
@click=${this.handleMoreInfo}
></paper-icon-button>
</div>
<div class="device-id">
${deviceID}
</div>
</ha-card>
`;
}
static get styles() {
return css`
paper-icon-button[highlight] {
color: var(--accent-color);
}
.card-content {
display: flex;
justify-content: center;
}
.placeholder {
width: 24px;
padding: 8px;
}
.device-id {
opacity: 0.7;
font-size: xx-small;
margin-top: -10px;
user-select: all;
-webkit-user-select: all;
-moz-user-select: all;
-ms-user-select: all;
}
`
}
}
customElements.define("browser-player", BrowserPlayer);

View File

@ -1,4 +1,6 @@
import {deviceID} from "/card-tools/deviceId" import {deviceID} from "/card-tools/deviceId"
import "./browser-player"
class BrowserMod { class BrowserMod {
constructor() { constructor() {
@ -73,13 +75,19 @@ class BrowserMod {
this.player.volume = msg.volume_level; this.player.volume = msg.volume_level;
} }
mute(msg) { mute(msg) {
if (msg.mute === undefined)
msg.mute = !this.player.muted;
this.player.muted = Boolean(msg.mute) this.player.muted = Boolean(msg.mute)
} }
update() { update(msg=null) {
if(!this.conn) return; if(!this.conn) return;
if(msg)
if(msg.entity_id)
this.entity_id = msg.entity_id;
this.conn.sendMessage({ this.conn.sendMessage({
type: 'browser_mod/update', type: 'browser_mod/update',
deviceID: deviceID, deviceID: deviceID,