diff --git a/README.md b/README.md index afce32c..85d4b8f 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,11 @@ This binds the *aliases* `arrakis` to `99980b13-dabc9563` and `dashboard` to `d2 Note: Aliases must be unique. + +#### Experimental: Custom deviceID +You can also set a deviceID by adding `?deviceID=mydeviceID` to the end of the URL you're using to access Home Assistant. Be careful - I have no idea what could happen if several devices were to have the same ID. +Use `?deviceID=clear` to generate a new random one. + ### Prefix You can add a custom prefix to all entity ids in `configuration.yaml`: diff --git a/custom_components/browser_mod/browser_mod.js b/custom_components/browser_mod/browser_mod.js index 0dcdbf4..e4a5336 100644 --- a/custom_components/browser_mod/browser_mod.js +++ b/custom_components/browser_mod/browser_mod.js @@ -1,4 +1,4 @@ -!function(e){var t={};function o(i){if(t[i])return t[i].exports;var s=t[i]={i:i,l:!1,exports:{}};return e[i].call(s.exports,s,s.exports,o),s.l=!0,s.exports}o.m=e,o.c=t,o.d=function(e,t,i){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},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 i=Object.create(null);if(o.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)o.d(i,s,function(t){return e[t]}.bind(null,s));return i},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=1)}([function(e){e.exports=JSON.parse('{"name":"browser_mod","private":true,"version":"1.1.5","description":"","scripts":{"build":"webpack","watch":"webpack --watch --mode=development","update-card-tools":"npm uninstall card-tools && npm install thomasloven/lovelace-card-tools"},"keywords":[],"author":"Thomas Lovén","license":"MIT","devDependencies":{"webpack":"^4.44.1","webpack-cli":"^3.3.12"},"dependencies":{"card-tools":"github:thomasloven/lovelace-card-tools"}}')},function(e,t,o){"use strict";o.r(t);let i=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"]}();function s(){return document.querySelector("hc-main")?document.querySelector("hc-main").hass:document.querySelector("home-assistant")?document.querySelector("home-assistant").hass:void 0}function a(e){return document.querySelector("hc-main")?document.querySelector("hc-main").provideHass(e):document.querySelector("home-assistant")?document.querySelector("home-assistant").provideHass(e):void 0}function n(){var e,t=document.querySelector("hc-main");return t?((e=t._lovelaceConfig).current_view=t._lovelacePath,e):(t=(t=(t=(t=(t=(t=(t=(t=(t=document.querySelector("home-assistant"))&&t.shadowRoot)&&t.querySelector("home-assistant-main"))&&t.shadowRoot)&&t.querySelector("app-drawer-layout partial-panel-resolver"))&&t.shadowRoot||t)&&t.querySelector("ha-panel-lovelace"))&&t.shadowRoot)&&t.querySelector("hui-root"))?((e=t.lovelace).current_view=t.___curView,e):null}function r(){var e=document.querySelector("hc-main");return e=e?(e=(e=(e=e&&e.shadowRoot)&&e.querySelector("hc-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-view")||e.querySelector("hui-panel-view"):(e=(e=(e=(e=(e=(e=(e=(e=(e=(e=(e=(e=document.querySelector("home-assistant"))&&e.shadowRoot)&&e.querySelector("home-assistant-main"))&&e.shadowRoot)&&e.querySelector("app-drawer-layout partial-panel-resolver"))&&e.shadowRoot||e)&&e.querySelector("ha-panel-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-root"))&&e.shadowRoot)&&e.querySelector("ha-app-layout"))&&e.querySelector("#view"))&&e.firstElementChild}async function l(){if(customElements.get("hui-view"))return!0;await customElements.whenDefined("partial-panel-resolver");const e=document.createElement("partial-panel-resolver");if(e.hass={panels:[{url_path:"tmp",component_name:"lovelace"}]},e._updateRoutes(),await e.routerOptions.routes.tmp.load(),!customElements.get("ha-panel-lovelace"))return!1;const t=document.createElement("ha-panel-lovelace");return t.hass=s(),void 0===t.hass&&(await new Promise(e=>{window.addEventListener("connection-status",t=>{console.log(t),e()},{once:!0})}),t.hass=s()),t.panel={config:{mode:null}},t._fetchConfig(),!0}async function c(e,t,o=!1){let i=e;"string"==typeof t&&(t=t.split(/(\$| )/));for(const[e,s]of t.entries())if(s.trim().length){if(!i)return null;i.localName&&i.localName.includes("-")&&await customElements.whenDefined(i.localName),i.updateComplete&&await i.updateComplete,i="$"===s?o&&e==t.length-1?[i.shadowRoot]:i.shadowRoot:o&&e==t.length-1?i.querySelectorAll(s):i.querySelector(s)}return i}async function d(e,t,o=!1,i=1e4){return Promise.race([c(e,t,o),new Promise((e,t)=>setTimeout(()=>t(new Error("timeout")),i))]).catch(e=>{if(!e.message||"timeout"!==e.message)throw e;return null})}function u(e,t,o=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},o)o.dispatchEvent(e);else{var i=r();i&&i.dispatchEvent(e)}}let h=window.cardHelpers;new Promise(async(e,t)=>{h&&e();const o=async()=>{h=await window.loadCardHelpers(),window.cardHelpers=h,e()};window.loadCardHelpers?o():window.addEventListener("load",async()=>{l(),window.loadCardHelpers&&o()})});async function m(e,t,o=!1,i={},s=!1){if(!customElements.get("card-tools-popup")){const e=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),t=e.prototype.html,o=e.prototype.css;class i extends e{static get properties(){return{open:{},large:{reflect:!0,type:Boolean},hass:{}}}updated(e){e.has("hass")&&this.card&&(this.card.hass=this.hass)}closeDialog(){this.open=!1}async _makeCard(){const e=await window.loadCardHelpers();this.card=await e.createCardElement(this._card),this.card.hass=this.hass,this.requestUpdate()}async _applyStyles(){let e=await d(this,"$ ha-dialog");customElements.whenDefined("card-mod").then(async()=>{if(!e)return;customElements.get("card-mod").applyToElement(e,"more-info",this._style,{config:this._card},[],!1)})}async showDialog(e,t,o=!1,i={},s=!1){this.title=e,this._card=t,this.large=o,this._style=i,this.fullscreen=!!s,this._makeCard(),await this.updateComplete,this.open=!0,await this._applyStyles()}_enlarge(){this.large=!this.large}render(){return this.open?t` +!function(e){var t={};function o(i){if(t[i])return t[i].exports;var s=t[i]={i:i,l:!1,exports:{}};return e[i].call(s.exports,s,s.exports,o),s.l=!0,s.exports}o.m=e,o.c=t,o.d=function(e,t,i){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},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 i=Object.create(null);if(o.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)o.d(i,s,function(t){return e[t]}.bind(null,s));return i},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=1)}([function(e){e.exports=JSON.parse('{"name":"browser_mod","private":true,"version":"1.1.6","description":"","scripts":{"build":"webpack","watch":"webpack --watch --mode=development","update-card-tools":"npm uninstall card-tools && npm install thomasloven/lovelace-card-tools"},"keywords":[],"author":"Thomas Lovén","license":"MIT","devDependencies":{"webpack":"^4.44.1","webpack-cli":"^3.3.12"},"dependencies":{"card-tools":"github:thomasloven/lovelace-card-tools"}}')},function(e,t,o){"use strict";o.r(t);const i="lovelace-player-device-id";function s(){if(!localStorage[i]){const e=()=>Math.floor(1e5*(1+Math.random())).toString(16).substring(1);window.fully&&"function"==typeof fully.getDeviceId?localStorage[i]=fully.getDeviceId():localStorage[i]=`${e()}${e()}-${e()}${e()}`}return localStorage[i]}let a=s();const n=new URLSearchParams(window.location.search);var r;function l(){return document.querySelector("hc-main")?document.querySelector("hc-main").hass:document.querySelector("home-assistant")?document.querySelector("home-assistant").hass:void 0}function c(e){return document.querySelector("hc-main")?document.querySelector("hc-main").provideHass(e):document.querySelector("home-assistant")?document.querySelector("home-assistant").provideHass(e):void 0}function d(){var e,t=document.querySelector("hc-main");return t?((e=t._lovelaceConfig).current_view=t._lovelacePath,e):(t=(t=(t=(t=(t=(t=(t=(t=(t=document.querySelector("home-assistant"))&&t.shadowRoot)&&t.querySelector("home-assistant-main"))&&t.shadowRoot)&&t.querySelector("app-drawer-layout partial-panel-resolver"))&&t.shadowRoot||t)&&t.querySelector("ha-panel-lovelace"))&&t.shadowRoot)&&t.querySelector("hui-root"))?((e=t.lovelace).current_view=t.___curView,e):null}function u(){var e=document.querySelector("hc-main");return e=e?(e=(e=(e=e&&e.shadowRoot)&&e.querySelector("hc-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-view")||e.querySelector("hui-panel-view"):(e=(e=(e=(e=(e=(e=(e=(e=(e=(e=(e=(e=document.querySelector("home-assistant"))&&e.shadowRoot)&&e.querySelector("home-assistant-main"))&&e.shadowRoot)&&e.querySelector("app-drawer-layout partial-panel-resolver"))&&e.shadowRoot||e)&&e.querySelector("ha-panel-lovelace"))&&e.shadowRoot)&&e.querySelector("hui-root"))&&e.shadowRoot)&&e.querySelector("ha-app-layout"))&&e.querySelector("#view"))&&e.firstElementChild}async function h(){if(customElements.get("hui-view"))return!0;await customElements.whenDefined("partial-panel-resolver");const e=document.createElement("partial-panel-resolver");if(e.hass={panels:[{url_path:"tmp",component_name:"lovelace"}]},e._updateRoutes(),await e.routerOptions.routes.tmp.load(),!customElements.get("ha-panel-lovelace"))return!1;const t=document.createElement("ha-panel-lovelace");return t.hass=l(),void 0===t.hass&&(await new Promise(e=>{window.addEventListener("connection-status",t=>{console.log(t),e()},{once:!0})}),t.hass=l()),t.panel={config:{mode:null}},t._fetchConfig(),!0}async function m(e,t,o=!1){let i=e;"string"==typeof t&&(t=t.split(/(\$| )/));for(const[e,s]of t.entries())if(s.trim().length){if(!i)return null;i.localName&&i.localName.includes("-")&&await customElements.whenDefined(i.localName),i.updateComplete&&await i.updateComplete,i="$"===s?o&&e==t.length-1?[i.shadowRoot]:i.shadowRoot:o&&e==t.length-1?i.querySelectorAll(s):i.querySelector(s)}return i}async function p(e,t,o=!1,i=1e4){return Promise.race([m(e,t,o),new Promise((e,t)=>setTimeout(()=>t(new Error("timeout")),i))]).catch(e=>{if(!e.message||"timeout"!==e.message)throw e;return null})}function w(e,t,o=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},o)o.dispatchEvent(e);else{var i=u();i&&i.dispatchEvent(e)}}n.get("deviceID")&&null!==(r=n.get("deviceID"))&&("clear"===r?localStorage.removeItem(i):localStorage[i]=r,a=s());let y=window.cardHelpers;new Promise(async(e,t)=>{y&&e();const o=async()=>{y=await window.loadCardHelpers(),window.cardHelpers=y,e()};window.loadCardHelpers?o():window.addEventListener("load",async()=>{h(),window.loadCardHelpers&&o()})});async function v(e,t,o=!1,i={},s=!1){if(!customElements.get("card-tools-popup")){const e=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),t=e.prototype.html,o=e.prototype.css;class i extends e{static get properties(){return{open:{},large:{reflect:!0,type:Boolean},hass:{}}}updated(e){e.has("hass")&&this.card&&(this.card.hass=this.hass)}closeDialog(){this.open=!1}async _makeCard(){const e=await window.loadCardHelpers();this.card=await e.createCardElement(this._card),this.card.hass=this.hass,this.requestUpdate()}async _applyStyles(){let e=await p(this,"$ ha-dialog");customElements.whenDefined("card-mod").then(async()=>{if(!e)return;customElements.get("card-mod").applyToElement(e,"more-info",this._style,{config:this._card},[],!1)})}async showDialog(e,t,o=!1,i={},s=!1){this.title=e,this._card=t,this.large=o,this._style=i,this.fullscreen=!!s,this._makeCard(),await this.updateComplete,this.open=!0,await this._applyStyles()}_enlarge(){this.large=!this.large}render(){return this.open?t` {if(e.state&&"cardToolsPopup"in e.state)if(e.state.cardToolsPopup){const{title:t,card:o,large:i,style:s,fullscreen:a}=e.state.params;m(t,o,i,s,a)}else r.closeDialog()};window.addEventListener("popstate",e),window._moreInfoDialogListener=!0}history.replaceState({cardToolsPopup:!1},""),history.pushState({cardToolsPopup:!0,params:{title:e,card:t,large:o,style:i,fullscreen:s}},""),r.showDialog(e,t,o,i,s)}async function p(e,t=!1){const o=document.querySelector("hc-main")||document.querySelector("home-assistant");u("hass-more-info",{entityId:e},o);const i=await d(o,"$ ha-more-info-dialog");return i.large=t,i}const w=[customElements.whenDefined("home-assistant-main"),customElements.whenDefined("hui-view")];Promise.race(w).then(()=>{const e=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),t=e.prototype.html;e.prototype.css;class o extends e{setConfig(e){}render(){return t` + `}}customElements.define("card-tools-popup",i)}const a=document.querySelector("home-assistant")||document.querySelector("hc-root");if(!a)return;let n=await p(a,"$ card-tools-popup");if(!n){n=document.createElement("card-tools-popup");const e=a.shadowRoot.querySelector("ha-more-info-dialog");e?a.shadowRoot.insertBefore(n,e):a.shadowRoot.appendChild(n),c(n)}if(!window._moreInfoDialogListener){const e=async e=>{if(e.state&&"cardToolsPopup"in e.state)if(e.state.cardToolsPopup){const{title:t,card:o,large:i,style:s,fullscreen:a}=e.state.params;v(t,o,i,s,a)}else n.closeDialog()};window.addEventListener("popstate",e),window._moreInfoDialogListener=!0}history.replaceState({cardToolsPopup:!1},""),history.pushState({cardToolsPopup:!0,params:{title:e,card:t,large:o,style:i,fullscreen:s}},""),n.showDialog(e,t,o,i,s)}async function g(e,t=!1){const o=document.querySelector("hc-main")||document.querySelector("home-assistant");w("hass-more-info",{entityId:e},o);const i=await p(o,"$ ha-more-info-dialog");return i&&(i.large=t),i}const _=[customElements.whenDefined("home-assistant-main"),customElements.whenDefined("hui-view")];Promise.race(_).then(()=>{const e=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),t=e.prototype.html;e.prototype.css;class o extends e{setConfig(e){}render(){return t`
Nothing to configure.
- `}}customElements.get("browser-player-editor")||(customElements.define("browser-player-editor",o),window.customCards=window.customCards||[],window.customCards.push({type:"browser-player",name:"Browser Player",preview:!0}))});const y=[customElements.whenDefined("home-assistant-main"),customElements.whenDefined("hui-view")];Promise.race(y).then(()=>{const e=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),t=e.prototype.html,o=e.prototype.css;customElements.get("browser-player")||customElements.define("browser-player",class extends e{static get properties(){return{hass:{}}}static getConfigElement(){return document.createElement("browser-player-editor")}static getStubConfig(){return{}}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){p("media_player."+window.browser_mod.entity_id)}handlePlayPause(e){window.browser_mod.player.paused?window.browser_mod.play({}):window.browser_mod.pause({})}render(){if(!window.browser_mod)return window.setTimeout(()=>this.requestUpdate(),100),t``;const e=window.browser_mod.player;return t` + `}}customElements.get("browser-player-editor")||(customElements.define("browser-player-editor",o),window.customCards=window.customCards||[],window.customCards.push({type:"browser-player",name:"Browser Player",preview:!0}))});const f=[customElements.whenDefined("home-assistant-main"),customElements.whenDefined("hui-view")];Promise.race(f).then(()=>{const e=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),t=e.prototype.html,o=e.prototype.css;customElements.get("browser-player")||customElements.define("browser-player",class extends e{static get properties(){return{hass:{}}}static getConfigElement(){return document.createElement("browser-player-editor")}static getStubConfig(){return{}}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){g("media_player."+window.browser_mod.entity_id)}handlePlayPause(e){window.browser_mod.player.paused?window.browser_mod.play({}):window.browser_mod.pause({})}render(){if(!window.browser_mod)return window.setTimeout(()=>this.requestUpdate(),100),t``;const e=window.browser_mod.player;return t`
- ${i} + ${a}
@@ -146,4 +146,4 @@ -moz-user-select: all; -ms-user-select: all; } - `}})});class v{set hass(e){if(!e)return;if(this._hass=e,this.hassPatched)return;const t=e.callService;e.callService=(e,o,s)=>{if(s&&s.deviceID)if(Array.isArray(s.deviceID)){const e=s.deviceID.indexOf("this");-1!==e&&((s=JSON.parse(JSON.stringify(s))).deviceID[e]=i)}else"this"===s.deviceID&&((s=JSON.parse(JSON.stringify(s))).deviceID=i);return t(e,o,s)},this.hassPatched=!0,document.querySelector("hc-main")?document.querySelector("hc-main").hassChanged(e,e):document.querySelector("home-assistant").hassChanged(e,e)}playOnce(e){this._video&&this._video.play(),window.browser_mod.playedOnce||(window.browser_mod.player.play(),window.browser_mod.playedOnce=!0)}async _load_lovelace(){if(!await l()){window.setTimeout(this._load_lovelace.bind(this),100)}}_connect(){window.hassConnection?window.hassConnection.then(e=>this.connect(e.conn)):window.setTimeout(()=>this._connect(),100)}constructor(){this.entity_id=i.replace("-","_"),this.cast=null!==document.querySelector("hc-main"),this.cast?this.connect(s().connection):(window.setTimeout(this._load_lovelace.bind(this),500),this._connect(),document.querySelector("home-assistant").addEventListener("hass-more-info",this.popup_card.bind(this))),this.player=new Audio,this.playedOnce=!1,this.autoclose_popup_active=!1;const e=this.update.bind(this);this.player.addEventListener("ended",e),this.player.addEventListener("play",e),this.player.addEventListener("pause",e),this.player.addEventListener("volumechange",e),document.addEventListener("visibilitychange",e),window.addEventListener("location-changed",e),window.addEventListener("click",this.playOnce),window.addEventListener("mousemove",this.no_blackout.bind(this)),window.addEventListener("mousedown",this.no_blackout.bind(this)),window.addEventListener("keydown",this.no_blackout.bind(this)),window.addEventListener("touchstart",this.no_blackout.bind(this)),a(this),window.fully&&(this._fullyMotion=!1,this._motionTimeout=void 0,fully.bind("screenOn","browser_mod.update();"),fully.bind("screenOff","browser_mod.update();"),fully.bind("pluggedAC","browser_mod.update();"),fully.bind("pluggedUSB","browser_mod.update();"),fully.bind("onBatteryLevelChanged","browser_mod.update();"),fully.bind("unplugged","browser_mod.update();"),fully.bind("networkReconnect","browser_mod.update();"),fully.bind("onMotion","browser_mod.fullyMotion();")),this._screenSaver=void 0,this._screenSaverTimer=void 0,this._screenSaverTime=0,this._blackout=document.createElement("div"),this._blackout.style.cssText="\n position: fixed;\n left: 0;\n top: 0;\n padding: 0;\n margin: 0;\n width: 100%;\n height: 100%;\n background: black;\n visibility: hidden;\n ",document.body.appendChild(this._blackout);const t=o(0);console.info(`%cBROWSER_MOD ${t.version} IS INSTALLED\n %cDeviceID: ${i}`,"color: green; font-weight: bold","")}connect(e){this.conn=e,e.subscribeMessage(e=>this.callback(e),{type:"browser_mod/connect",deviceID:i})}callback(e){switch(e.command){case"update":this.update(e);break;case"debug":this.debug(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);break;case"toast":this.toast(e);break;case"popup":this.popup(e);break;case"close-popup":this.close_popup(e);break;case"navigate":this.navigate(e);break;case"more-info":this.more_info(e);break;case"set-theme":this.set_theme(e);break;case"lovelace-reload":this.lovelace_reload(e);break;case"blackout":this.blackout(e);break;case"no-blackout":this.no_blackout(e)}}get player_state(){return this.player.src?this.player.ended?"stopped":this.player.paused?"paused":"playing":"stopped"}popup_card(e){if(!n())return;const t=n(),o={...t.config.popup_cards,...t.config.views[t.current_view].popup_cards};if(!e.detail||!e.detail.entityId)return;const i=o[e.detail.entityId];i&&window.setTimeout(()=>{u("hass-more-info",{entityId:"."},document.querySelector("home-assistant")),m(i.title,i.card,i.large||!1,i.style)},50)}debug(e){m("deviceID",{type:"markdown",content:"# "+i}),alert(i)}_set_screensaver(e,t){if(clearTimeout(this._screenSaverTimer),e){if(-1==(t=parseInt(t)))return clearTimeout(this._screenSaverTimer),void(this._screenSaverTime=0);this._screenSaverTime=1e3*t,this._screenSaver=e,this._screenSaverTimer=setTimeout(this._screenSaver,this._screenSaverTime)}else this._screenSaverTime&&(this._screenSaverTimer=setTimeout(this._screenSaver,this._screenSaverTime))}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)}toast(e){e.message&&u("hass-notification",{message:e.message,duration:void 0!==e.duration?parseInt(e.duration):void 0},document.querySelector("home-assistant"))}popup(e){if(!e.title&&!e.auto_close)return;if(!e.card)return;const t=()=>{m(e.title,e.card,e.large,e.style,e.auto_close||e.hide_header),e.auto_close&&(this.autoclose_popup_active=!0)};e.auto_close&&e.time?this._set_screensaver(t,e.time):t()}close_popup(e){this._set_screensaver(),this.autoclose_popup_active=!1,async function(){const e=document.querySelector("home-assistant")||document.querySelector("hc-root");u("hass-more-info",{entityId:"."},e);const t=await d(e,"$ card-tools-popup");t&&t.closeDialog()}()}navigate(e){e.navigation_path&&(history.pushState(null,"",e.navigation_path),u("location-changed",{},document.querySelector("home-assistant")))}more_info(e){e.entity_id&&p(e.entity_id,e.large)}set_theme(e){e.theme||(e.theme="default"),u("settheme",e.theme,document.querySelector("home-assistant"))}lovelace_reload(e){const t=r();t&&u("config-refresh",{},t)}blackout(e){const t=()=>{window.fully?fully.turnScreenOff():this._blackout.style.visibility="visible",this.update()};e.time?this._set_screensaver(t,e.time):t()}no_blackout(e){if(this._set_screensaver(),this.autoclose_popup_active)return this.close_popup();window.fully?(fully.getScreenOn()||fully.turnScreenOn(),e.brightness&&fully.setScreenBrightness(e.brightness),this.update()):"hidden"!==this._blackout.style.visibility&&(this._blackout.style.visibility="hidden",this.update())}is_blackout(){return window.fully?!fully.getScreenOn():Boolean("visible"===this._blackout.style.visibility)}fullyMotion(){this._fullyMotion=!0,clearTimeout(this._motionTimeout),this._motionTimeout=setTimeout(()=>{this._fullyMotion=!1,this.update()},5e3),this.update()}start_camera(){this._video||(this._video=document.createElement("video"),this._video.autoplay=!0,this._video.playsInline=!0,this._video.style.cssText="\n visibility: hidden;\n width: 0;\n height: 0;\n ",this._canvas=document.createElement("canvas"),this._canvas.style.cssText="\n visibility: hidden;\n width: 0;\n height: 0;\n ",document.body.appendChild(this._canvas),document.body.appendChild(this._video),navigator.mediaDevices.getUserMedia({video:!0,audio:!1}).then(e=>{this._video.srcObject=e,this._video.play(),this.send_cam()}))}send_cam(e){this._canvas.getContext("2d").drawImage(this._video,0,0,this._canvas.width,this._canvas.height),this.conn.sendMessage({type:"browser_mod/update",deviceID:i,data:{camera:this._canvas.toDataURL("image/png")}}),setTimeout(this.send_cam.bind(this),5e3)}update(e=null){this.conn&&(e&&(e.name&&(this.entity_id=e.name.toLowerCase()),e.camera&&this.start_camera()),this.conn.sendMessage({type:"browser_mod/update",deviceID:i,data:{browser:{path:window.location.pathname,visibility:document.visibilityState,userAgent:navigator.userAgent,currentUser:this._hass&&this._hass.user&&this._hass.user.name,fullyKiosk:!!window.fully||void 0,width:window.innerWidth,height:window.innerHeight},player:{volume:this.player.volume,muted:this.player.muted,src:this.player.src,state:this.player_state},screen:{blackout:this.is_blackout(),brightness:window.fully?fully.getScreenBrightness():void 0},fully:window.fully?{battery:window.fully?fully.getBatteryLevel():void 0,charging:window.fully?fully.isPlugged():void 0,motion:window.fully?this._fullyMotion:void 0}:void 0}}))}}const g=[customElements.whenDefined("home-assistant-main"),customElements.whenDefined("hui-view")];Promise.race(g).then(()=>{window.browser_mod=window.browser_mod||new v})}]); \ No newline at end of file + `}})});class b{set hass(e){if(!e)return;if(this._hass=e,this.hassPatched)return;const t=e.callService;e.callService=(e,o,i)=>{if(i&&i.deviceID)if(Array.isArray(i.deviceID)){const e=i.deviceID.indexOf("this");-1!==e&&((i=JSON.parse(JSON.stringify(i))).deviceID[e]=a)}else"this"===i.deviceID&&((i=JSON.parse(JSON.stringify(i))).deviceID=a);return t(e,o,i)},this.hassPatched=!0,document.querySelector("hc-main")?document.querySelector("hc-main").hassChanged(e,e):document.querySelector("home-assistant").hassChanged(e,e)}playOnce(e){this._video&&this._video.play(),window.browser_mod.playedOnce||(window.browser_mod.player.play(),window.browser_mod.playedOnce=!0)}async _load_lovelace(){if(!await h()){window.setTimeout(this._load_lovelace.bind(this),100)}}_connect(){window.hassConnection?window.hassConnection.then(e=>this.connect(e.conn)):window.setTimeout(()=>this._connect(),100)}constructor(){this.entity_id=a.replace("-","_"),this.cast=null!==document.querySelector("hc-main"),this.cast?this.connect(l().connection):(window.setTimeout(this._load_lovelace.bind(this),500),this._connect(),document.querySelector("home-assistant").addEventListener("hass-more-info",this.popup_card.bind(this))),this.player=new Audio,this.playedOnce=!1,this.autoclose_popup_active=!1;const e=this.update.bind(this);this.player.addEventListener("ended",e),this.player.addEventListener("play",e),this.player.addEventListener("pause",e),this.player.addEventListener("volumechange",e),document.addEventListener("visibilitychange",e),window.addEventListener("location-changed",e),window.addEventListener("click",this.playOnce),window.addEventListener("mousemove",this.no_blackout.bind(this)),window.addEventListener("mousedown",this.no_blackout.bind(this)),window.addEventListener("keydown",this.no_blackout.bind(this)),window.addEventListener("touchstart",this.no_blackout.bind(this)),c(this),window.fully&&(this._fullyMotion=!1,this._motionTimeout=void 0,fully.bind("screenOn","browser_mod.update();"),fully.bind("screenOff","browser_mod.update();"),fully.bind("pluggedAC","browser_mod.update();"),fully.bind("pluggedUSB","browser_mod.update();"),fully.bind("onBatteryLevelChanged","browser_mod.update();"),fully.bind("unplugged","browser_mod.update();"),fully.bind("networkReconnect","browser_mod.update();"),fully.bind("onMotion","browser_mod.fullyMotion();")),this._screenSaver=void 0,this._screenSaverTimer=void 0,this._screenSaverTime=0,this._blackout=document.createElement("div"),this._blackout.style.cssText="\n position: fixed;\n left: 0;\n top: 0;\n padding: 0;\n margin: 0;\n width: 100%;\n height: 100%;\n background: black;\n visibility: hidden;\n ",document.body.appendChild(this._blackout);const t=o(0);console.info(`%cBROWSER_MOD ${t.version} IS INSTALLED\n %cDeviceID: ${a}`,"color: green; font-weight: bold","")}connect(e){this.conn=e,e.subscribeMessage(e=>this.callback(e),{type:"browser_mod/connect",deviceID:a})}callback(e){switch(e.command){case"update":this.update(e);break;case"debug":this.debug(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);break;case"toast":this.toast(e);break;case"popup":this.popup(e);break;case"close-popup":this.close_popup(e);break;case"navigate":this.navigate(e);break;case"more-info":this.more_info(e);break;case"set-theme":this.set_theme(e);break;case"lovelace-reload":this.lovelace_reload(e);break;case"blackout":this.blackout(e);break;case"no-blackout":this.no_blackout(e)}}get player_state(){return this.player.src?this.player.ended?"stopped":this.player.paused?"paused":"playing":"stopped"}popup_card(e){if(!d())return;const t=d(),o={...t.config.popup_cards,...t.config.views[t.current_view].popup_cards};if(!e.detail||!e.detail.entityId)return;const i=o[e.detail.entityId];i&&window.setTimeout(()=>{w("hass-more-info",{entityId:"."},document.querySelector("home-assistant")),v(i.title,i.card,i.large||!1,i.style)},50)}debug(e){v("deviceID",{type:"markdown",content:"# "+a}),alert(a)}_set_screensaver(e,t){if(clearTimeout(this._screenSaverTimer),e){if(-1==(t=parseInt(t)))return clearTimeout(this._screenSaverTimer),void(this._screenSaverTime=0);this._screenSaverTime=1e3*t,this._screenSaver=e,this._screenSaverTimer=setTimeout(this._screenSaver,this._screenSaverTime)}else this._screenSaverTime&&(this._screenSaverTimer=setTimeout(this._screenSaver,this._screenSaverTime))}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)}toast(e){e.message&&w("hass-notification",{message:e.message,duration:void 0!==e.duration?parseInt(e.duration):void 0},document.querySelector("home-assistant"))}popup(e){if(!e.title&&!e.auto_close)return;if(!e.card)return;const t=()=>{v(e.title,e.card,e.large,e.style,e.auto_close||e.hide_header),e.auto_close&&(this.autoclose_popup_active=!0)};e.auto_close&&e.time?this._set_screensaver(t,e.time):t()}close_popup(e){this._set_screensaver(),this.autoclose_popup_active=!1,async function(){const e=document.querySelector("home-assistant")||document.querySelector("hc-root");w("hass-more-info",{entityId:"."},e);const t=await p(e,"$ card-tools-popup");t&&t.closeDialog()}()}navigate(e){e.navigation_path&&(history.pushState(null,"",e.navigation_path),w("location-changed",{},document.querySelector("home-assistant")))}more_info(e){e.entity_id&&g(e.entity_id,e.large)}set_theme(e){e.theme||(e.theme="default"),w("settheme",e.theme,document.querySelector("home-assistant"))}lovelace_reload(e){const t=u();t&&w("config-refresh",{},t)}blackout(e){const t=()=>{window.fully?fully.turnScreenOff():this._blackout.style.visibility="visible",this.update()};e.time?this._set_screensaver(t,e.time):t()}no_blackout(e){if(this._set_screensaver(),this.autoclose_popup_active)return this.close_popup();window.fully?(fully.getScreenOn()||fully.turnScreenOn(),e.brightness&&fully.setScreenBrightness(e.brightness),this.update()):"hidden"!==this._blackout.style.visibility&&(this._blackout.style.visibility="hidden",this.update())}is_blackout(){return window.fully?!fully.getScreenOn():Boolean("visible"===this._blackout.style.visibility)}fullyMotion(){this._fullyMotion=!0,clearTimeout(this._motionTimeout),this._motionTimeout=setTimeout(()=>{this._fullyMotion=!1,this.update()},5e3),this.update()}start_camera(){this._video||(this._video=document.createElement("video"),this._video.autoplay=!0,this._video.playsInline=!0,this._video.style.cssText="\n visibility: hidden;\n width: 0;\n height: 0;\n ",this._canvas=document.createElement("canvas"),this._canvas.style.cssText="\n visibility: hidden;\n width: 0;\n height: 0;\n ",document.body.appendChild(this._canvas),document.body.appendChild(this._video),navigator.mediaDevices.getUserMedia({video:!0,audio:!1}).then(e=>{this._video.srcObject=e,this._video.play(),this.send_cam()}))}send_cam(e){this._canvas.getContext("2d").drawImage(this._video,0,0,this._canvas.width,this._canvas.height),this.conn.sendMessage({type:"browser_mod/update",deviceID:a,data:{camera:this._canvas.toDataURL("image/png")}}),setTimeout(this.send_cam.bind(this),5e3)}update(e=null){this.conn&&(e&&(e.name&&(this.entity_id=e.name.toLowerCase()),e.camera&&this.start_camera()),this.conn.sendMessage({type:"browser_mod/update",deviceID:a,data:{browser:{path:window.location.pathname,visibility:document.visibilityState,userAgent:navigator.userAgent,currentUser:this._hass&&this._hass.user&&this._hass.user.name,fullyKiosk:!!window.fully||void 0,width:window.innerWidth,height:window.innerHeight},player:{volume:this.player.volume,muted:this.player.muted,src:this.player.src,state:this.player_state},screen:{blackout:this.is_blackout(),brightness:window.fully?fully.getScreenBrightness():void 0},fully:window.fully?{battery:window.fully?fully.getBatteryLevel():void 0,charging:window.fully?fully.isPlugged():void 0,motion:window.fully?this._fullyMotion:void 0}:void 0}}))}}const S=[customElements.whenDefined("home-assistant-main"),customElements.whenDefined("hui-view")];Promise.race(S).then(()=>{window.browser_mod=window.browser_mod||new b})}]); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 81f29f9..9d205f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "browser_mod", - "version": "1.1.4", + "version": "1.1.6", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -655,7 +655,7 @@ "dev": true }, "card-tools": { - "version": "github:thomasloven/lovelace-card-tools#951759b56acfcfb5d1aa8222bf410a9a36712182", + "version": "github:thomasloven/lovelace-card-tools#6d5ae3800e4937aa424edc17108f43b964aecce7", "from": "github:thomasloven/lovelace-card-tools" }, "chalk": { diff --git a/package.json b/package.json index 8164554..17d331b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "browser_mod", "private": true, - "version": "1.1.5", + "version": "1.1.6", "description": "", "scripts": { "build": "webpack", diff --git a/test/lovelace.yaml b/test/lovelace.yaml index a178e72..1a78838 100644 --- a/test/lovelace.yaml +++ b/test/lovelace.yaml @@ -9,95 +9,20 @@ views: - title: Player cards: - type: custom:browser-player - - type: button - class: border - entity: sun.sun - name: popup - tap_action: - action: call-service - service: browser_mod.popup - service_data: - deviceID: this - title: Test - card: - type: markdown - content: Hello! - - - type: button - entity: sun.sun - name: large - tap_action: - action: call-service - service: browser_mod.popup - service_data: - deviceID: this - title: Test - large: true - card: - type: markdown - content: Hello! - - - type: button - entity: sun.sun - name: Style - tap_action: - action: call-service - service: browser_mod.popup - service_data: - deviceID: this - title: Test + - type: picture-elements + image: https://placekitten.com/g/800/600 + elements: + - type: state-icon + entity: light.bed_light style: - .: | - app-toolbar { - background: rgba(0,0,0,0.5) !important; - } - $: | - .mdc-dialog .mdc-dialog__container .mdc-dialog__surface { - border-radius: 20px; - background: rgba(0,0,0,0); - } - card: - type: vertical-stack - cards: - - type: markdown - content: Hello! - style: | - ha-card { - --ha-card-background: rgba(0,0,0,0.5); - color: white; - } - - type: markdown - content: Hello! - style: | - ha-card { - --ha-card-background: rgba(0,0,0,0.5); - color: red; - } + top: 50% + left: 50% + animation: spin 4s linear infinite + style: | + @keyframes spin { + 100% { + transform: rotate(360deg); + } + } - - type: button - entity: sun.sun - name: Auto Close - tap_action: - action: call-service - service: browser_mod.popup - service_data: - deviceID: this - title: Test - auto_close: true - card: - type: markdown - content: Hello! - - - type: button - entity: sun.sun - name: Hide Header - tap_action: - action: call-service - service: browser_mod.popup - service_data: - deviceID: this - title: Test - hide_header: true - card: - type: markdown - content: Hello! + - !include views/popup.yaml diff --git a/test/views/popup.yaml b/test/views/popup.yaml new file mode 100644 index 0000000..835efad --- /dev/null +++ b/test/views/popup.yaml @@ -0,0 +1,232 @@ +x-anchors: + default: &default + type: button + entity: light.bed_light + icon: mdi:settings + + desc: &desc + type: markdown + style: | + code { + font-size: 8pt; + line-height: normal; + white-space: pre-wrap; + } + +title: Popup +cards: + - type: vertical-stack + cards: + - <<: *desc + content: | + ``` + service: browser_mod.popup + service_data: + title: Default + card: + type: markdown + content: Popup! + ``` + - <<: *default + name: Default + tap_action: + action: call-service + service: browser_mod.popup + service_data: + title: Default + card: + type: markdown + content: Popup! + + - type: vertical-stack + cards: + - <<: *desc + content: | + ``` + service: browser_mod.popup + service_data: + title: Large + large: true + card: + type: markdown + content: Popup! + ``` + - <<: *default + name: Large + tap_action: + action: call-service + service: browser_mod.popup + service_data: + title: Large + large: true + card: + type: markdown + content: Popup! + + - type: vertical-stack + cards: + - <<: *desc + content: | + ``` + service: browser_mod.popup + service_data: + title: Hide Header + hide_header: true + card: + type: markdown + content: Popup! + ``` + - <<: *default + name: Hide header + tap_action: + action: call-service + service: browser_mod.popup + service_data: + title: Hide Header + hide_header: true + card: + type: markdown + content: Popup! + + - type: vertical-stack + cards: + - <<: *desc + content: | + ``` + service: browser_mod.popup + service_data: + title: Auto close + auto_close: true + card: + type: markdown + content: Popup! + ``` + - <<: *default + name: Auto close + tap_action: + action: call-service + service: browser_mod.popup + service_data: + title: Auto close + auto_close: true + card: + type: markdown + content: Popup! + + - type: vertical-stack + cards: + - <<: *desc + content: | + ``` + service: browser_mod.popup + service_data: + title: Popup 1 + card: + <<: *default + tap_action: + action: call-service + service: browser_mod.popup + service_data: + title: Popup 2 + card: + type: markdown + content: Popup! + ``` + - <<: *default + name: Nested popup + tap_action: + action: call-service + service: browser_mod.popup + service_data: + title: Popup 1 + card: + <<: *default + tap_action: + action: call-service + service: browser_mod.popup + service_data: + title: Popup 2 + card: + type: markdown + content: Popup! + + - type: vertical-stack + cards: + - <<: *desc + content: | + More info in popup. + May have different behavior depending on whether a more-info dialog + has ever been opened before a popup. + - type: entities + entities: [light.bed_light] + - <<: *default + name: More info in popup + tap_action: + action: call-service + service: browser_mod.popup + service_data: + title: More info in popup + card: + type: entities + entities: [light.bed_light] + + - type: vertical-stack + cards: + - <<: *desc + content: | + ``` + style: + $: | + .mdc-dialog { + backdrop-filter: blur(17px); + -webkit-backdrop-filter: blur(17px); + } + .mdc-dialog .mdc-dialog__container .mdc-dialog__surface { + border-radius: 25px; + } + .: | + :host { + --mdc-theme-surface: rgba(0,0,0,0); + --secondary-background-color: rgba(0,0,0,0.5); + --ha-card-background: rgba(0,0,0,0.5); + } + :host .content { + width: 90vw; + height: 90vh; + } + ``` + - <<: *default + name: Styled + tap_action: + action: call-service + service: browser_mod.popup + service_data: + title: Styled popup + card: + type: markdown + content: Popup! + style: + $: | + .mdc-dialog { + backdrop-filter: blur(17px); + -webkit-backdrop-filter: blur(17px); + } + .mdc-dialog .mdc-dialog__container .mdc-dialog__surface { + border-radius: 25px; + } + .: | + :host { + --mdc-theme-surface: rgba(0,0,0,0); + --secondary-background-color: rgba(0,0,0,0.5); + --ha-card-background: rgba(0,0,0,0.5); + } + :host .content { + width: 90vw; + height: 90vh; + } + + - <<: *default + name: Close popup + tap_action: + action: call-service + service: browser_mod.close_popup