From 5f34d95040a56a3fb459153082d3307f53306ab6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Sun, 8 Dec 2019 23:22:47 +0100 Subject: [PATCH] Popup-card functionality --- README.md | 43 ++++++++++++++++++++ custom_components/browser_mod/browser_mod.js | 8 ++-- js/main.js | 19 ++++++++- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 374aff3..424fc18 100644 --- a/README.md +++ b/README.md @@ -327,6 +327,49 @@ Second, there are a few more attributes available | `charging` | Whether the battery is currently charging. | | `motion` | Whether the devices camera has detected any motion in the last five seconds. | +# Replacing more-info dialogs +With browser_mod, you can replace any more-info dialog with any lovelace card you choose yourself. This can be done either per lovelace view, or globally (even outside of lovelace). + +The replacement is included in your lovelace or lovelace view configuration, and the syntax is exactly like the `popup` service, except you can't use `auto_close` or `time`. + +Ex: +```yaml +views: + - title: Home view + icon: mdi:house + popup_cards: + light.ceiling_light: + title: My popup + card: + type: entities + entities: + - light.ceiling_light_bulb1 + - light.ceiling_light_bulb2 + - light.ceiling_light_bulb3 + - light.ceiling_light_bulb4 +``` + +This would show an entities card with four bulbs any time the more-info dialog for `light.ceiling_light` would normally be shown when you're on the Home view in lovelace. + +```yaml +title: My home +resources: + - url: /local/card-mod.js + type: module +popup_cards: + sensor.sensor1: + title: First sensor + card: + type: gauge + entity: sensor.sensor1 + sensor.sensor2: + title: Second sensor + card: + type: gauge + entity: sensor.sensor2 +``` +This would replace the more-info dialogs of `sensor.sensor1` and `sensor.sensor2` anywhere in your interface. Even outside of lovelace - be careful about that. + # Support [Home Assistant community forum thread](https://community.home-assistant.io/t/browser-mod-turn-your-browser-into-a-controllable-device-and-a-media-player/123806) diff --git a/custom_components/browser_mod/browser_mod.js b/custom_components/browser_mod/browser_mod.js index 6beb1a8..a6c3e70 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(s){if(t[s])return t[s].exports;var i=t[s]={i:s,l:!1,exports:{}};return e[s].call(i.exports,i,i.exports,o),i.l=!0,i.exports}o.m=e,o.c=t,o.d=function(e,t,s){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},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 s=Object.create(null);if(o.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)o.d(s,i,function(t){return e[t]}.bind(null,i));return s},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 s=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 i(e){return document.querySelector("home-assistant").provideHass(e)}function n(){if(customElements.get("hui-view"))return!0;const e=document.createElement("partial-panel-resolver");if(e.hass=document.querySelector("home-assistant").hass,!e.hass||!e.hass.panels)return!1;e.route={path:"/lovelace/"},e._updateRoutes();try{document.querySelector("home-assistant").appendChild(e)}catch(e){}finally{document.querySelector("home-assistant").removeChild(e)}return!!customElements.get("hui-view")}function r(e,t,o=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},o)o.dispatchEvent(e);else{var s=document.querySelector("home-assistant");(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=s&&s.shadowRoot)&&s.querySelector("home-assistant-main"))&&s.shadowRoot)&&s.querySelector("app-drawer-layout partial-panel-resolver"))&&s.shadowRoot||s)&&s.querySelector("ha-panel-lovelace"))&&s.shadowRoot)&&s.querySelector("hui-root"))&&s.shadowRoot)&&s.querySelector("ha-app-layout #view"))&&s.firstElementChild)&&s.dispatchEvent(e)}}const a="custom:";function l(e,t){const o=document.createElement("hui-error-card");return o.setConfig({type:"error",error:e,origConfig:t}),o}function c(e,t){if(!t||"object"!=typeof t||!t.type)return l(`No ${e} type configured`,t);let o=t.type;if(o=o.startsWith(a)?o.substr(a.length):`hui-${o}-${e}`,customElements.get(o))return function(e,t){const o=document.createElement(e);try{o.setConfig(t)}catch(e){return l(e,t)}return o}(o,t);const s=l(`Custom element doesn't exist: ${o}.`,t);s.style.display="None";const i=setTimeout(()=>{s.style.display=""},2e3);return customElements.whenDefined(o).then(()=>{clearTimeout(i),r("ll-rebuild",{},s)}),s}function d(e,t=!1){r("hass-more-info",{entityId:e},document.querySelector("home-assistant"));const o=document.querySelector("home-assistant")._moreInfoEl;return o.large=t,o}const u=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),h=u.prototype.html,p=u.prototype.css,m=2;class y extends u{static get version(){return m}static get properties(){return{noHass:{type:Boolean}}}setConfig(e){this._config=e,this.el?this.el.setConfig(e):(this.el=this.create(e),this._hass&&(this.el.hass=this._hass),this.noHass&&i(this))}set config(e){this.setConfig(e)}set hass(e){this._hass=e,this.el&&(this.el.hass=e)}createRenderRoot(){return this}render(){return h`${this.el}`}}const v=function(e,t){const o=Object.getOwnPropertyDescriptors(t.prototype);for(const[t,s]of Object.entries(o))"constructor"!==t&&Object.defineProperty(e.prototype,t,s);const s=Object.getOwnPropertyDescriptors(t);for(const[t,o]of Object.entries(s))"prototype"!==t&&Object.defineProperty(e,t,o);const i=Object.getPrototypeOf(t),n=Object.getOwnPropertyDescriptors(i.prototype);for(const[t,o]of Object.entries(n))"constructor"!==t&&Object.defineProperty(Object.getPrototypeOf(e).prototype,t,o);const r=Object.getOwnPropertyDescriptors(i);for(const[t,o]of Object.entries(r))"prototype"!==t&&Object.defineProperty(Object.getPrototypeOf(e),t,o)},f=customElements.get("card-maker");if(!f||!f.version||f.version\n app-toolbar {\n color: var(--more-info-header-color);\n background-color: var(--more-info-header-background);\n }\n .scrollable {\n overflow: auto;\n max-width: 100% !important;\n }\n \n ${i?"":`\n \n \n
\n ${e}\n
\n
\n `}\n
\n \n \n
\n `;const l=a.querySelector(".scrollable");l.querySelector("card-maker").config=t,n.sizingTarget=l,n.large=o,n._page="none",n.shadowRoot.appendChild(a);let c={};if(s)for(var d in n.resetFit(),s)c[d]=n.style[d],n.style.setProperty(d,s[d]);return n._dialogOpenChanged=function(e){if(!e&&(this.stateObj&&this.fire("hass-more-info",{entityId:null}),this.shadowRoot==a.parentNode&&(this._page=null,this.shadowRoot.removeChild(a),s)))for(var t in n.resetFit(),c)c[t]?n.style.setProperty(t,c[t]):n.style.removeProperty(t)},n}customElements.define("browser-player",class extends u{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){d(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 h` +!function(e){var t={};function o(s){if(t[s])return t[s].exports;var i=t[s]={i:s,l:!1,exports:{}};return e[s].call(i.exports,i,i.exports,o),i.l=!0,i.exports}o.m=e,o.c=t,o.d=function(e,t,s){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},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 s=Object.create(null);if(o.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)o.d(s,i,function(t){return e[t]}.bind(null,i));return s},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 s=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 i(e){return document.querySelector("home-assistant").provideHass(e)}function n(){var e=document.querySelector("home-assistant");if(e=(e=(e=(e=(e=(e=(e=(e=e&&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")){var t=e.lovelace;return t.current_view=e.___curView,t}return null}function r(){if(customElements.get("hui-view"))return!0;const e=document.createElement("partial-panel-resolver");if(e.hass=document.querySelector("home-assistant").hass,!e.hass||!e.hass.panels)return!1;e.route={path:"/lovelace/"},e._updateRoutes();try{document.querySelector("home-assistant").appendChild(e)}catch(e){}finally{document.querySelector("home-assistant").removeChild(e)}return!!customElements.get("hui-view")}function a(e,t,o=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},o)o.dispatchEvent(e);else{var s=document.querySelector("home-assistant");(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=(s=s&&s.shadowRoot)&&s.querySelector("home-assistant-main"))&&s.shadowRoot)&&s.querySelector("app-drawer-layout partial-panel-resolver"))&&s.shadowRoot||s)&&s.querySelector("ha-panel-lovelace"))&&s.shadowRoot)&&s.querySelector("hui-root"))&&s.shadowRoot)&&s.querySelector("ha-app-layout #view"))&&s.firstElementChild)&&s.dispatchEvent(e)}}const l="custom:";function c(e,t){const o=document.createElement("hui-error-card");return o.setConfig({type:"error",error:e,origConfig:t}),o}function d(e,t){if(!t||"object"!=typeof t||!t.type)return c(`No ${e} type configured`,t);let o=t.type;if(o=o.startsWith(l)?o.substr(l.length):`hui-${o}-${e}`,customElements.get(o))return function(e,t){const o=document.createElement(e);try{o.setConfig(t)}catch(e){return c(e,t)}return o}(o,t);const s=c(`Custom element doesn't exist: ${o}.`,t);s.style.display="None";const i=setTimeout(()=>{s.style.display=""},2e3);return customElements.whenDefined(o).then(()=>{clearTimeout(i),a("ll-rebuild",{},s)}),s}function u(e,t=!1){a("hass-more-info",{entityId:e},document.querySelector("home-assistant"));const o=document.querySelector("home-assistant")._moreInfoEl;return o.large=t,o}const h=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),p=h.prototype.html,m=h.prototype.css,y=2;class v extends h{static get version(){return y}static get properties(){return{noHass:{type:Boolean}}}setConfig(e){this._config=e,this.el?this.el.setConfig(e):(this.el=this.create(e),this._hass&&(this.el.hass=this._hass),this.noHass&&i(this))}set config(e){this.setConfig(e)}set hass(e){this._hass=e,this.el&&(this.el.hass=e)}createRenderRoot(){return this}render(){return p`${this.el}`}}const f=function(e,t){const o=Object.getOwnPropertyDescriptors(t.prototype);for(const[t,s]of Object.entries(o))"constructor"!==t&&Object.defineProperty(e.prototype,t,s);const s=Object.getOwnPropertyDescriptors(t);for(const[t,o]of Object.entries(s))"prototype"!==t&&Object.defineProperty(e,t,o);const i=Object.getPrototypeOf(t),n=Object.getOwnPropertyDescriptors(i.prototype);for(const[t,o]of Object.entries(n))"constructor"!==t&&Object.defineProperty(Object.getPrototypeOf(e).prototype,t,o);const r=Object.getOwnPropertyDescriptors(i);for(const[t,o]of Object.entries(r))"prototype"!==t&&Object.defineProperty(Object.getPrototypeOf(e),t,o)},_=customElements.get("card-maker");if(!_||!_.version||_.version\n app-toolbar {\n color: var(--more-info-header-color);\n background-color: var(--more-info-header-background);\n }\n .scrollable {\n overflow: auto;\n max-width: 100% !important;\n }\n \n ${i?"":`\n \n \n
\n ${e}\n
\n
\n `}\n
\n \n \n
\n `;const l=r.querySelector(".scrollable");l.querySelector("card-maker").config=t,n.sizingTarget=l,n.large=o,n._page="none",n.shadowRoot.appendChild(r);let c={};if(s)for(var d in n.resetFit(),s)c[d]=n.style[d],n.style.setProperty(d,s[d]);return n._dialogOpenChanged=function(e){if(!e&&(this.stateObj&&this.fire("hass-more-info",{entityId:null}),this.shadowRoot==r.parentNode&&(this._page=null,this.shadowRoot.removeChild(r),s)))for(var t in n.resetFit(),c)c[t]?n.style.setProperty(t,c[t]):n.style.removeProperty(t)},n}customElements.define("browser-player",class extends h{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){u(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 p`
- ${"stopped"===window.browser_mod.player_state?h`
`:h` + ${"stopped"===window.browser_mod.player_state?p`
`:p` - `}static get styles(){return p` + `}static get styles(){return m` paper-icon-button[highlight] { color: var(--accent-color); } @@ -53,4 +53,4 @@ -moz-user-select: all; -ms-user-select: all; } - `}});window.browser_mod=new class{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.deviceID[e]=s)}else"this"===i.deviceID&&(i.deviceID=s);return t(e,o,i)},this.hassPatched=!0,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)}_load_lovelace(){if(!n()){window.setTimeout(this._load_lovelace.bind(this),100)}}constructor(){window.setTimeout(this._load_lovelace.bind(this),500),window.hassConnection.then(e=>this.connect(e.conn)),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)),i(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)}connect(e){this.conn=e,e.subscribeMessage(e=>this.callback(e),{type:"browser_mod/connect",deviceID:s})}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"}debug(e){g("deviceID",{type:"markdown",content:`# ${s}`}),alert(s)}_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&&r("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=()=>{g(e.title,e.card,e.large,e.style,e.auto_close),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,function(){const e=document.querySelector("home-assistant")&&document.querySelector("home-assistant")._moreInfoEl;e&&e.close()}()}navigate(e){e.navigation_path&&(history.pushState(null,"",e.navigation_path),r("location-changed",{},document.querySelector("home-assistant")))}more_info(e){e.entity_id&&d(e.entity_id,e.large)}set_theme(e){e.theme||(e.theme="default"),r("settheme",e.theme,document.querySelector("home-assistant"))}lovelace_reload(e){const t=o=(o=(o=(o=(o=(o=(o=(o=(o=(o=(o=(o=document.querySelector("home-assistant"))&&o.shadowRoot)&&o.querySelector("home-assistant-main"))&&o.shadowRoot)&&o.querySelector("app-drawer-layout partial-panel-resolver"))&&o.shadowRoot||o)&&o.querySelector("ha-panel-lovelace"))&&o.shadowRoot)&&o.querySelector("hui-root"))&&o.shadowRoot)&&o.querySelector("ha-app-layout #view"))&&o.firstElementChild;var o;t&&r("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:s,data:{camera:this._canvas.toDataURL("image/png")}}),setTimeout(this.send_cam.bind(this),5e3)}update(e=null){this.conn&&(e&&(e.entity_id&&(this.entity_id=e.entity_id),e.camera&&this.start_camera()),this.conn.sendMessage({type:"browser_mod/update",deviceID:s,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}}))}}}]); \ No newline at end of file + `}});window.browser_mod=new class{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.deviceID[e]=s)}else"this"===i.deviceID&&(i.deviceID=s);return t(e,o,i)},this.hassPatched=!0,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)}_load_lovelace(){if(!r()){window.setTimeout(this._load_lovelace.bind(this),100)}}constructor(){window.setTimeout(this._load_lovelace.bind(this),500),window.hassConnection.then(e=>this.connect(e.conn)),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)),i(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)}connect(e){this.conn=e,e.subscribeMessage(e=>this.callback(e),{type:"browser_mod/connect",deviceID:s})}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){const t=document.querySelector("home-assistant")._moreInfoEl;if(t&&!t.getAttribute("aria-hidden"))return;if(!n())return;const o=n(),s={...o.config.popup_cards,...o.config.views[o.current_view].popup_cards};if(!e.detail||!e.detail.entityId)return;const i=s[e.detail.entityId];i&&w(i.title,i.card,i.large||!1,i.style)}debug(e){w("deviceID",{type:"markdown",content:`# ${s}`}),alert(s)}_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&&a("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=()=>{w(e.title,e.card,e.large,e.style,e.auto_close),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,function(){const e=document.querySelector("home-assistant")&&document.querySelector("home-assistant")._moreInfoEl;e&&e.close()}()}navigate(e){e.navigation_path&&(history.pushState(null,"",e.navigation_path),a("location-changed",{},document.querySelector("home-assistant")))}more_info(e){e.entity_id&&u(e.entity_id,e.large)}set_theme(e){e.theme||(e.theme="default"),a("settheme",e.theme,document.querySelector("home-assistant"))}lovelace_reload(e){const t=o=(o=(o=(o=(o=(o=(o=(o=(o=(o=(o=(o=document.querySelector("home-assistant"))&&o.shadowRoot)&&o.querySelector("home-assistant-main"))&&o.shadowRoot)&&o.querySelector("app-drawer-layout partial-panel-resolver"))&&o.shadowRoot||o)&&o.querySelector("ha-panel-lovelace"))&&o.shadowRoot)&&o.querySelector("hui-root"))&&o.shadowRoot)&&o.querySelector("ha-app-layout #view"))&&o.firstElementChild;var o;t&&a("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:s,data:{camera:this._canvas.toDataURL("image/png")}}),setTimeout(this.send_cam.bind(this),5e3)}update(e=null){this.conn&&(e&&(e.entity_id&&(this.entity_id=e.entity_id),e.camera&&this.start_camera()),this.conn.sendMessage({type:"browser_mod/update",deviceID:s,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}}))}}}]); \ No newline at end of file diff --git a/js/main.js b/js/main.js index a1b9b03..37614a0 100644 --- a/js/main.js +++ b/js/main.js @@ -1,5 +1,5 @@ import { deviceID } from "card-tools/src/deviceId"; -import { lovelace_view, provideHass, load_lovelace } from "card-tools/src/hass"; +import { lovelace_view, provideHass, load_lovelace, lovelace } from "card-tools/src/hass"; import { popUp, closePopUp } from "card-tools/src/popup"; import { fireEvent } from "card-tools/src/event"; import { moreInfo } from "card-tools/src/more-info.js"; @@ -46,6 +46,7 @@ class BrowserMod { constructor() { window.setTimeout(this._load_lovelace.bind(this), 500); window.hassConnection.then((conn) => this.connect(conn.conn)); + document.querySelector("home-assistant").addEventListener("hass-more-info", this.popup_card.bind(this)); this.player = new Audio(); this.playedOnce = false; @@ -171,6 +172,22 @@ class BrowserMod { return "playing"; } + popup_card(ev) { + const moreInfoEl = document.querySelector("home-assistant")._moreInfoEl; + if(moreInfoEl && !moreInfoEl.getAttribute('aria-hidden')) return; + if(!lovelace()) return; + const ll = lovelace(); + const data = { + ...ll.config.popup_cards, + ...ll.config.views[ll.current_view].popup_cards, + }; + + if(!ev.detail || !ev.detail.entityId) return; + const d = data[ev.detail.entityId]; + if(!d) return; + popUp(d.title, d.card, d.large || false, d.style); + } + debug(msg) { popUp(`deviceID`, {type: "markdown", content: `# ${deviceID}`}) alert(deviceID);