mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-06 14:39:22 +00:00
@@ -1,125 +1,125 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "816ff9c893e23b7441e73210f85024741ff6c5bf8dabd2fb0df9e8b8055bc693",
|
||||
"fingerprint": "b69bdfe3df225cf1b96fea0159a03a620e38cb94ec6106f9ee3b0e57cdefd183",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js",
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 291031,
|
||||
"initialViewGzipBytes": 290942,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/de-DJX-vLW1.js",
|
||||
"houseplan-assets/editor-Dvui5H3b.js",
|
||||
"houseplan-assets/fr-DVmfM6Kw.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-9AEP51ly.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-CnVK5oOC.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/de-CDRfP4mw.js",
|
||||
"houseplan-assets/editor-Bze_fgW0.js",
|
||||
"houseplan-assets/fr-B64rhazj.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-X23eakN9.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C3A8efgN.js"
|
||||
],
|
||||
"lazyGzipBytes": 214972,
|
||||
"lazyGzipBytes": 215441,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/editor-Dvui5H3b.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-9AEP51ly.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/editor-Bze_fgW0.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-X23eakN9.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 159157,
|
||||
"lazyEditorGzipBytes": 159770,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-CnVK5oOC.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C3A8efgN.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 14132,
|
||||
"lazyOnboardingGzipBytes": 14129,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-DJX-vLW1.js",
|
||||
"houseplan-assets/fr-DVmfM6Kw.js"
|
||||
"houseplan-assets/de-CDRfP4mw.js",
|
||||
"houseplan-assets/fr-B64rhazj.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 48859,
|
||||
"lazyLocaleGzipBytes": 48717,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"sha256": "455450cbc7b74f052fb112680af9ba4be145af8c3a1061907ec541b63957f22f",
|
||||
"path": "houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"sha256": "7becca609cbb95b1ba278743fce5b3e93c7adf8a7bd9107783931f29279ac5df",
|
||||
"rawBytes": 20974,
|
||||
"gzipBytes": 7176,
|
||||
"gzipBytes": 7175,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-DJX-vLW1.js",
|
||||
"sha256": "73d198680c17602addf41855748533ed47233e81e9bdc02a786034aeac0e4e63",
|
||||
"rawBytes": 81798,
|
||||
"gzipBytes": 24701,
|
||||
"path": "houseplan-assets/de-CDRfP4mw.js",
|
||||
"sha256": "2f90acc29e659e771dea42290b74ceb54d8ab9a7fae9cfdbd7ce6bc4bda0b70b",
|
||||
"rawBytes": 81632,
|
||||
"gzipBytes": 24630,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-Dvui5H3b.js",
|
||||
"sha256": "11578ded60410e4e879c9342ee74c8a0968477ea2bae98eb18480a0ad02d303c",
|
||||
"path": "houseplan-assets/editor-Bze_fgW0.js",
|
||||
"sha256": "2e2513efca4fa8d9019c3601693fb3ff3b9e050ba3fe054b190f81d286540dda",
|
||||
"rawBytes": 3826,
|
||||
"gzipBytes": 1580,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-DVmfM6Kw.js",
|
||||
"sha256": "167bed2822ce7e2b38d47e8dc1d73648d10c04d469979bf05e414000b53487b4",
|
||||
"rawBytes": 83973,
|
||||
"gzipBytes": 24158,
|
||||
"path": "houseplan-assets/fr-B64rhazj.js",
|
||||
"sha256": "6a1a18220938a8d4631586a9dc7f8ef8243b77a23089777d0917975300960a82",
|
||||
"rawBytes": 83754,
|
||||
"gzipBytes": 24087,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-Dwkibvgo.js",
|
||||
"sha256": "d16deb0fc6f591040a2f97d51102e3e355da35cb3d1b69aa79472406c28d3ed2",
|
||||
"rawBytes": 1033612,
|
||||
"gzipBytes": 290234,
|
||||
"path": "houseplan-assets/houseplan-card-CxS6HLVV.js",
|
||||
"sha256": "1607bc6eeb275b340391ff10bdb7c2c5f62e59d5d2a43adbdb412698a0a024d1",
|
||||
"rawBytes": 1032923,
|
||||
"gzipBytes": 290148,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-DJX-vLW1.js",
|
||||
"houseplan-assets/editor-Dvui5H3b.js",
|
||||
"houseplan-assets/fr-DVmfM6Kw.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-9AEP51ly.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-CnVK5oOC.js"
|
||||
"houseplan-assets/de-CDRfP4mw.js",
|
||||
"houseplan-assets/editor-Bze_fgW0.js",
|
||||
"houseplan-assets/fr-B64rhazj.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-X23eakN9.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C3A8efgN.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-9AEP51ly.js",
|
||||
"sha256": "c1b8f90458afedddbbdde98570c517d6e66dfcee08ad4764b1ac2473bdf89fb4",
|
||||
"rawBytes": 574225,
|
||||
"gzipBytes": 150401,
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-X23eakN9.js",
|
||||
"sha256": "53f256fffc8e6f02618e56dbf56f25258356c2ca221ee9918ccbc57d9e590f6b",
|
||||
"rawBytes": 575918,
|
||||
"gzipBytes": 151015,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-CnVK5oOC.js",
|
||||
"sha256": "bd169896116229e76b37243106bde64755589017639890d36dd19282c872db7a",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-C3A8efgN.js",
|
||||
"sha256": "a5433ef2715f424016b31a2ae3c3c30f2cff05549230fd0ab16db3159834de3f",
|
||||
"rawBytes": 28088,
|
||||
"gzipBytes": 6956,
|
||||
"gzipBytes": 6954,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "730163666440793e44be0ee5482f7080931370f94555a1d52072d3a54698447e",
|
||||
"sha256": "f9d93e5aa355fc91dc8fad57e7669a0ac663e8b538f42ea671a1a319fe214c3e",
|
||||
"rawBytes": 1183,
|
||||
"gzipBytes": 797,
|
||||
"gzipBytes": 794,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
+7
-7
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+5
-5
@@ -1,14 +1,14 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="816ff9c893e23b7441e73210f85024741ff6c5bf8dabd2fb0df9e8b8055bc693";import{b as e,l as o,t,df as s,A as a,dg as i,dh as l,di as n,E as r,c}from"./houseplan-card-Dwkibvgo.js";class f extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,f={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},h=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="b69bdfe3df225cf1b96fea0159a03a620e38cb94ec6106f9ee3b0e57cdefd183";import{b as e,l as o,t,dg as s,A as a,dh as i,di as l,dj as n,E as r,c}from"./houseplan-card-CxS6HLVV.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
.computeLabel=${e=>f[e.name]||e.name}
|
||||
.computeLabel=${e=>h[e.name]||e.name}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>`;return c`
|
||||
${d(h.slice(0,3))}
|
||||
${d(f.slice(0,3))}
|
||||
${_?c`<div class="default-floor-error" role="alert"
|
||||
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
|
||||
${t(s,"editor.default_floor_missing",{id:_})}
|
||||
</div>`:a}
|
||||
${d(h.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
|
||||
${d(f.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+101
-101
File diff suppressed because one or more lines are too long
+110
-106
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="816ff9c893e23b7441e73210f85024741ff6c5bf8dabd2fb0df9e8b8055bc693";try{await import("./houseplan-assets/houseplan-card-Dwkibvgo.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale entry: the main chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="b69bdfe3df225cf1b96fea0159a03a620e38cb94ec6106f9ee3b0e57cdefd183";try{await import("./houseplan-assets/houseplan-card-CxS6HLVV.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale entry: the main chunk is unavailable",e)}
|
||||
|
||||
@@ -140,6 +140,9 @@ def _global_settings(value: object) -> dict[str, Any]:
|
||||
out = _copy_keys(value, ("glow_radius_cm", "bg_color", "north_deg", "bg_mode", "sun_rays"))
|
||||
if not isinstance(value, dict):
|
||||
return out
|
||||
show_room_tooltip = value.get("show_room_tooltip")
|
||||
if isinstance(show_room_tooltip, bool):
|
||||
out["show_room_tooltip"] = show_room_tooltip
|
||||
fill_colors = value.get("fill_colors")
|
||||
if isinstance(fill_colors, dict):
|
||||
out["fill_colors"] = {
|
||||
|
||||
@@ -1935,6 +1935,7 @@ CONFIG_SCHEMA = vol.All(
|
||||
vol.Optional("north_deg"): _north_deg,
|
||||
vol.Optional("bg_mode"): _BG_MODE,
|
||||
vol.Optional("sun_rays"): bool,
|
||||
vol.Optional("show_room_tooltip"): bool,
|
||||
# Removed from the UI/runtime in 2026-08-08. Keep accepting the
|
||||
# legacy field so an existing stored config can still load; the
|
||||
# frontend ignores it and removes it on the next settings save.
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import { launch, checkAll, finish } from './serve.mjs';
|
||||
|
||||
const { page, browser } = await launch();
|
||||
const result = await page.evaluate(async () => {
|
||||
const card = window.__card;
|
||||
const root = () => card.shadowRoot || card.renderRoot;
|
||||
const room = () => root().querySelector('.room');
|
||||
const mouse = (type, x, y) => new PointerEvent(type, {
|
||||
pointerType: 'mouse', bubbles: true, composed: true, clientX: x, clientY: y,
|
||||
});
|
||||
const out = {};
|
||||
|
||||
card._openSettingsDialog();
|
||||
await card.updateComplete;
|
||||
const settingRow = [...root().querySelectorAll('hp-dialog label.srcrow')]
|
||||
.find((label) => label.textContent.trim() === 'Show the room information window on hover');
|
||||
out.localizedControl = !!settingRow?.querySelector('ha-switch,input[type="checkbox"]');
|
||||
out.defaultOn = card._settingsDialog?.showRoomTooltip === true;
|
||||
|
||||
card._settingsDialog = { ...card._settingsDialog, showRoomTooltip: false };
|
||||
card._settingsDialog = null;
|
||||
out.cancelKeepsAbsentDefault = !Object.hasOwn(card._serverCfg.settings, 'show_room_tooltip');
|
||||
|
||||
room().dispatchEvent(mouse('pointerenter', 180, 180));
|
||||
room().dispatchEvent(mouse('pointermove', 180, 180));
|
||||
await card.updateComplete;
|
||||
out.defaultRoomTip = card._tip?.room === true && !!root().querySelector('.tip');
|
||||
|
||||
card._openSettingsDialog();
|
||||
card._settingsDialog = { ...card._settingsDialog, showRoomTooltip: false };
|
||||
await card._saveSettingsDialog();
|
||||
await card.updateComplete;
|
||||
out.falsePersists = card._serverCfg.settings.show_room_tooltip === false;
|
||||
out.visibleRoomTipCleared = card._tip === null && !root().querySelector('.tip');
|
||||
|
||||
let roomAreaCalls = 0;
|
||||
const originalRoomArea = card._roomArea.bind(card);
|
||||
card._roomArea = (...args) => {
|
||||
roomAreaCalls += 1;
|
||||
return originalRoomArea(...args);
|
||||
};
|
||||
room().dispatchEvent(mouse('pointerenter', 190, 190));
|
||||
room().dispatchEvent(mouse('pointermove', 190, 190));
|
||||
await card.updateComplete;
|
||||
out.disabledRoomTip = card._tip === null && !root().querySelector('.tip');
|
||||
out.disabledSkipsArea = roomAreaCalls === 0;
|
||||
out.roomHighlightSurvives = card._hoverRoom !== null
|
||||
&& !!root().querySelector('.room-hover-fill-layer,.room-hover-outline-layer');
|
||||
|
||||
root().querySelector('.dev').dispatchEvent(mouse('pointermove', 200, 200));
|
||||
await card.updateComplete;
|
||||
out.deviceTipSurvives = card._tip?.room === false && !!root().querySelector('.tip');
|
||||
|
||||
card._openSettingsDialog();
|
||||
out.reopenShowsOff = card._settingsDialog?.showRoomTooltip === false;
|
||||
card._settingsDialog = { ...card._settingsDialog, showRoomTooltip: true };
|
||||
await card._saveSettingsDialog();
|
||||
await card.updateComplete;
|
||||
out.trueStoredAsAbsent = !Object.hasOwn(card._serverCfg.settings, 'show_room_tooltip');
|
||||
out.enableDoesNotRestoreStaleTip = card._tip?.room !== true;
|
||||
|
||||
room().dispatchEvent(mouse('pointermove', 210, 210));
|
||||
await card.updateComplete;
|
||||
out.roomTipRestoredOnMove = card._tip?.room === true && !!root().querySelector('.tip');
|
||||
return out;
|
||||
});
|
||||
|
||||
checkAll(result, {
|
||||
localizedControl: true,
|
||||
defaultOn: true,
|
||||
cancelKeepsAbsentDefault: true,
|
||||
defaultRoomTip: true,
|
||||
falsePersists: true,
|
||||
visibleRoomTipCleared: true,
|
||||
disabledRoomTip: true,
|
||||
disabledSkipsArea: true,
|
||||
roomHighlightSurvives: true,
|
||||
deviceTipSurvives: true,
|
||||
reopenShowsOff: true,
|
||||
trueStoredAsAbsent: true,
|
||||
enableDoesNotRestoreStaleTip: true,
|
||||
roomTipRestoredOnMove: true,
|
||||
});
|
||||
await finish(browser, result);
|
||||
Vendored
+58
-58
@@ -1,125 +1,125 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "816ff9c893e23b7441e73210f85024741ff6c5bf8dabd2fb0df9e8b8055bc693",
|
||||
"fingerprint": "b69bdfe3df225cf1b96fea0159a03a620e38cb94ec6106f9ee3b0e57cdefd183",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js",
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 291031,
|
||||
"initialViewGzipBytes": 290942,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/de-DJX-vLW1.js",
|
||||
"houseplan-assets/editor-Dvui5H3b.js",
|
||||
"houseplan-assets/fr-DVmfM6Kw.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-9AEP51ly.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-CnVK5oOC.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/de-CDRfP4mw.js",
|
||||
"houseplan-assets/editor-Bze_fgW0.js",
|
||||
"houseplan-assets/fr-B64rhazj.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-X23eakN9.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C3A8efgN.js"
|
||||
],
|
||||
"lazyGzipBytes": 214972,
|
||||
"lazyGzipBytes": 215441,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/editor-Dvui5H3b.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-9AEP51ly.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/editor-Bze_fgW0.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-X23eakN9.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 159157,
|
||||
"lazyEditorGzipBytes": 159770,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-CnVK5oOC.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C3A8efgN.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 14132,
|
||||
"lazyOnboardingGzipBytes": 14129,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-DJX-vLW1.js",
|
||||
"houseplan-assets/fr-DVmfM6Kw.js"
|
||||
"houseplan-assets/de-CDRfP4mw.js",
|
||||
"houseplan-assets/fr-B64rhazj.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 48859,
|
||||
"lazyLocaleGzipBytes": 48717,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"sha256": "455450cbc7b74f052fb112680af9ba4be145af8c3a1061907ec541b63957f22f",
|
||||
"path": "houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"sha256": "7becca609cbb95b1ba278743fce5b3e93c7adf8a7bd9107783931f29279ac5df",
|
||||
"rawBytes": 20974,
|
||||
"gzipBytes": 7176,
|
||||
"gzipBytes": 7175,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-DJX-vLW1.js",
|
||||
"sha256": "73d198680c17602addf41855748533ed47233e81e9bdc02a786034aeac0e4e63",
|
||||
"rawBytes": 81798,
|
||||
"gzipBytes": 24701,
|
||||
"path": "houseplan-assets/de-CDRfP4mw.js",
|
||||
"sha256": "2f90acc29e659e771dea42290b74ceb54d8ab9a7fae9cfdbd7ce6bc4bda0b70b",
|
||||
"rawBytes": 81632,
|
||||
"gzipBytes": 24630,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-Dvui5H3b.js",
|
||||
"sha256": "11578ded60410e4e879c9342ee74c8a0968477ea2bae98eb18480a0ad02d303c",
|
||||
"path": "houseplan-assets/editor-Bze_fgW0.js",
|
||||
"sha256": "2e2513efca4fa8d9019c3601693fb3ff3b9e050ba3fe054b190f81d286540dda",
|
||||
"rawBytes": 3826,
|
||||
"gzipBytes": 1580,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-DVmfM6Kw.js",
|
||||
"sha256": "167bed2822ce7e2b38d47e8dc1d73648d10c04d469979bf05e414000b53487b4",
|
||||
"rawBytes": 83973,
|
||||
"gzipBytes": 24158,
|
||||
"path": "houseplan-assets/fr-B64rhazj.js",
|
||||
"sha256": "6a1a18220938a8d4631586a9dc7f8ef8243b77a23089777d0917975300960a82",
|
||||
"rawBytes": 83754,
|
||||
"gzipBytes": 24087,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-Dwkibvgo.js",
|
||||
"sha256": "d16deb0fc6f591040a2f97d51102e3e355da35cb3d1b69aa79472406c28d3ed2",
|
||||
"rawBytes": 1033612,
|
||||
"gzipBytes": 290234,
|
||||
"path": "houseplan-assets/houseplan-card-CxS6HLVV.js",
|
||||
"sha256": "1607bc6eeb275b340391ff10bdb7c2c5f62e59d5d2a43adbdb412698a0a024d1",
|
||||
"rawBytes": 1032923,
|
||||
"gzipBytes": 290148,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-DJX-vLW1.js",
|
||||
"houseplan-assets/editor-Dvui5H3b.js",
|
||||
"houseplan-assets/fr-DVmfM6Kw.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-9AEP51ly.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-CnVK5oOC.js"
|
||||
"houseplan-assets/de-CDRfP4mw.js",
|
||||
"houseplan-assets/editor-Bze_fgW0.js",
|
||||
"houseplan-assets/fr-B64rhazj.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-X23eakN9.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-C3A8efgN.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-9AEP51ly.js",
|
||||
"sha256": "c1b8f90458afedddbbdde98570c517d6e66dfcee08ad4764b1ac2473bdf89fb4",
|
||||
"rawBytes": 574225,
|
||||
"gzipBytes": 150401,
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-X23eakN9.js",
|
||||
"sha256": "53f256fffc8e6f02618e56dbf56f25258356c2ca221ee9918ccbc57d9e590f6b",
|
||||
"rawBytes": 575918,
|
||||
"gzipBytes": 151015,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-CnVK5oOC.js",
|
||||
"sha256": "bd169896116229e76b37243106bde64755589017639890d36dd19282c872db7a",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-C3A8efgN.js",
|
||||
"sha256": "a5433ef2715f424016b31a2ae3c3c30f2cff05549230fd0ab16db3159834de3f",
|
||||
"rawBytes": 28088,
|
||||
"gzipBytes": 6956,
|
||||
"gzipBytes": 6954,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-DWD0ZQTc.js",
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/backdrop-pick-I85bKcdl.js",
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "730163666440793e44be0ee5482f7080931370f94555a1d52072d3a54698447e",
|
||||
"sha256": "f9d93e5aa355fc91dc8fad57e7669a0ac663e8b538f42ea671a1a319fe214c3e",
|
||||
"rawBytes": 1183,
|
||||
"gzipBytes": 797,
|
||||
"gzipBytes": 794,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-Dwkibvgo.js"
|
||||
"houseplan-assets/houseplan-card-CxS6HLVV.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
Vendored
+7
-7
File diff suppressed because one or more lines are too long
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
+5
-5
@@ -1,14 +1,14 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="816ff9c893e23b7441e73210f85024741ff6c5bf8dabd2fb0df9e8b8055bc693";import{b as e,l as o,t,df as s,A as a,dg as i,dh as l,di as n,E as r,c}from"./houseplan-card-Dwkibvgo.js";class f extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,f={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},h=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="b69bdfe3df225cf1b96fea0159a03a620e38cb94ec6106f9ee3b0e57cdefd183";import{b as e,l as o,t,dg as s,A as a,dh as i,di as l,dj as n,E as r,c}from"./houseplan-card-CxS6HLVV.js";class h extends e{constructor(){super(...arguments),this._spaces=null,this._spacesLoading=!1,this._spacesAuthoritative=!1}setConfig(e){this._config=e}async _loadSpaces(){if(!this._spaces&&!this._spacesLoading&&this.hass){this._spacesLoading=!0;try{const e=await this.hass.callWS({type:"houseplan/config/get"});this._spaces=(e?.config?.spaces||[]).map(e=>({value:e.id,label:e.title||e.id})),this._spacesAuthoritative=!0}catch{this._spaces=[],this._spacesAuthoritative=!1}finally{this._spacesLoading=!1}}}get _lang(){return o(this.hass,this._config?.language)}get _floorToken(){const e=this._config?.floor;return"number"==typeof e?`__houseplan_yaml_floor_index__:${String(e)}`:null}get _formData(){const e={...this._config},o=this._floorToken;return o?e.floor=o:Object.prototype.hasOwnProperty.call(e,"floor")||(e.floor=""),e}get _schema(){const e=this._spaces||[],o=this._lang,a=[{value:"",label:t(o,"editor.floor_none")}],i=this._floorToken;i&&a.push({value:i,label:t(o,"editor.floor_index",{index:String(this._config?.floor)})});const l="string"==typeof this._config?.floor?this._config.floor:"";l&&!e.some(e=>e.value===l)&&a.push({value:l,label:l}),a.push(...e);const n="string"==typeof this._config?.default_floor?this._config.default_floor:"",r=[...e];return n&&!e.some(e=>e.value===n)&&r.unshift({value:n,label:n}),[{name:"title",selector:{text:{}}},{name:"floor",selector:{select:{mode:"dropdown",options:a}}},e.length?{name:"default_floor",selector:{select:{mode:"dropdown",options:r}}}:{name:"default_floor",selector:{text:{}}},{name:"language",selector:{select:{mode:"dropdown",options:s(t(o,"editor.lang_auto"),this._config?.language)}}},{name:"icon_size",selector:{number:{min:1,max:6,step:.1,mode:"box"}}},{name:"show_temperature",selector:{boolean:{}}},{name:"live_states",selector:{boolean:{}}},{name:"show_signal",selector:{boolean:{}}},{name:"kiosk",selector:{boolean:{}}},{name:"cycle",selector:{number:{min:0,max:3600,step:5,mode:"box"}}}]}render(){if(!this.hass||!this._config)return a;const e=i(this,l,o(this.hass,this._config.language));if("cold"===e)return n();if("warm"===e)return r;this._loadSpaces();const s=this._lang,h={title:t(s,"editor.title"),floor:t(s,"editor.floor"),default_floor:t(s,"editor.default_floor"),language:t(s,"editor.language"),icon_size:t(s,"editor.icon_size"),show_temperature:t(s,"editor.show_temperature"),live_states:t(s,"editor.live_states"),show_signal:t(s,"editor.show_signal"),kiosk:t(s,"editor.kiosk"),cycle:t(s,"editor.cycle")},f=this._schema,_=function(e,o,t){if(!t||null===o)return null;const s="string"==typeof e?.default_floor?e.default_floor:"";return!s||o.some(e=>e.value===s)?null:s}(this._config,this._spaces,this._spacesAuthoritative),d=e=>c`<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._formData}
|
||||
.schema=${e}
|
||||
.computeLabel=${e=>f[e.name]||e.name}
|
||||
.computeLabel=${e=>h[e.name]||e.name}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>`;return c`
|
||||
${d(h.slice(0,3))}
|
||||
${d(f.slice(0,3))}
|
||||
${_?c`<div class="default-floor-error" role="alert"
|
||||
style="color:var(--error-color,#db4437);margin:-4px 0 12px;overflow-wrap:anywhere">
|
||||
${t(s,"editor.default_floor_missing",{id:_})}
|
||||
</div>`:a}
|
||||
${d(h.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}f.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",f);
|
||||
${d(f.slice(3))}
|
||||
`}_valueChanged(e){const o={...this._config,...e.detail.value};""===o.floor?delete o.floor:o.floor===this._floorToken&&(o.floor=this._config?.floor);const t=new Event("config-changed",{bubbles:!0,composed:!0});t.detail={config:o},this.dispatchEvent(t)}}h.properties={hass:{attribute:!1},_config:{state:!0},_spaces:{state:!0}},customElements.get("houseplan-card-editor")||customElements.define("houseplan-card-editor",h);
|
||||
Vendored
+1
File diff suppressed because one or more lines are too long
Vendored
-1
File diff suppressed because one or more lines are too long
Vendored
+101
-101
File diff suppressed because one or more lines are too long
+110
-106
File diff suppressed because one or more lines are too long
+4
-4
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="816ff9c893e23b7441e73210f85024741ff6c5bf8dabd2fb0df9e8b8055bc693";try{await import("./houseplan-assets/houseplan-card-Dwkibvgo.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale entry: the main chunk is unavailable",e)}
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="b69bdfe3df225cf1b96fea0159a03a620e38cb94ec6106f9ee3b0e57cdefd183";try{await import("./houseplan-assets/houseplan-card-CxS6HLVV.js")}catch(e){if(!customElements.get("houseplan-card")){const l=String(navigator.language||"en").toLowerCase();const m=l.startsWith("ru")?"House Plan обновился — перезагрузите страницу (Ctrl+F5).":l.startsWith("de")?"House Plan wurde aktualisiert — bitte laden Sie die Seite neu (Strg+F5).":l.startsWith("fr")?"House Plan a été mis à jour — veuillez recharger la page (Ctrl+F5).":"House Plan was updated — please reload the page (Ctrl+F5).";customElements.define("houseplan-card",class extends HTMLElement{setConfig(){}getCardSize(){return 1}connectedCallback(){this.style.cssText="display:block;box-sizing:border-box;padding:16px;border:1px solid var(--divider-color,#e0e0e0);border-radius:var(--ha-card-border-radius,12px);background:var(--card-background-color,#fff);color:var(--primary-text-color,#212121);font:14px/1.4 var(--paper-font-body1_-_font-family,sans-serif)";this.textContent=m}})}console.error("[houseplan] stale entry: the main chunk is unavailable",e)}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- General settings can now hide the room information window on mouse hover
|
||||
without disabling the room highlight or device tooltips; existing plans keep
|
||||
the window enabled by default ([#426](https://github.com/Matysh/houseplan-card/issues/426)).
|
||||
|
||||
## v1.71.0-beta.1 — 2026-09-03
|
||||
|
||||
- The Background editor can now upload and reuse private PNG, JPEG, WebP and
|
||||
|
||||
@@ -8,6 +8,11 @@
|
||||
|
||||
## Не выпущено
|
||||
|
||||
- В общих настройках теперь можно отключить информационное окно комнаты при
|
||||
наведении мышью, не отключая подсветку комнаты и подсказки устройств;
|
||||
существующие планы сохраняют включённое поведение по умолчанию
|
||||
([#426](https://github.com/Matysh/houseplan-card/issues/426)).
|
||||
|
||||
## v1.71.0-beta.1 — 2026-09-03
|
||||
|
||||
- В редакторе подложки теперь можно загружать и повторно использовать закрытые
|
||||
|
||||
@@ -63,6 +63,20 @@ writer produce the same request; accepting either would reopen last-writer-wins
|
||||
data loss. This changes only the WebSocket write contract. Stored config,
|
||||
model/store versions, exports and read compatibility are unchanged.
|
||||
|
||||
## Room hover information preference (#426)
|
||||
|
||||
`settings.show_room_tooltip` is an optional global boolean. Absence and any
|
||||
invalid legacy/future value read as the historical enabled default; only exact
|
||||
`false` hides the floating room information window. Saving the enabled value
|
||||
removes the key. The field does not change room highlighting or device
|
||||
tooltips, and does not require a model/store version migration.
|
||||
|
||||
An older frontend ignores the field and temporarily shows the room window. An
|
||||
older backend preserves it through the existing unknown-settings policy, so a
|
||||
new frontend restores the disabled behavior after upgrade. Full backup/import
|
||||
preserves the setting and the privacy-safe support projection includes only a
|
||||
validated boolean.
|
||||
|
||||
## Stable wall identity — model v8 (#282)
|
||||
|
||||
Model v8 adds `space.wall_segments[]`, ordered `rooms[].wall_ids[]`, IDs on
|
||||
|
||||
@@ -1024,6 +1024,10 @@ separately promised workflows:
|
||||
- [ ] Room hover adds a subtle accent wash and double contour without changing
|
||||
the underlying room fill or Glow brightness
|
||||
- [ ] Room tooltip shows average room temperature and humidity after the area line and before LQI; missing values are omitted [auto: smoke_ux_fixes]
|
||||
- [ ] General settings can hide only the room tooltip: default/Cancel/save/reopen
|
||||
semantics, skipped area work, persistent room highlight, unaffected
|
||||
device tooltip and restoration on the next mouse move
|
||||
[auto: smoke_room_tooltip_toggle]
|
||||
- [ ] Average room temperature counts ONLY thermometer/air-monitor devices — fridges, TRV heads,
|
||||
smart-plug chip temperatures (`*_device_temperature`) and diagnostic-category temps are excluded [manual]
|
||||
- [ ] Space dialog is 500 px wide; the comfort-bounds inputs are compact (56 px)
|
||||
|
||||
@@ -51,6 +51,11 @@ desktop hover without a reload. Space/mode changes, page hiding and remounts
|
||||
also discard transient hover. Keyboard focus and explicit click/tap surfaces
|
||||
remain independent of this visual hover gate.
|
||||
|
||||
The default-on **Show the room information window on hover** preference applies
|
||||
only after this pointer-modality gate has enabled real mouse hover. Turning it
|
||||
off leaves the room highlight and device tooltips unchanged; it does not add a
|
||||
touch or pen replacement for the room window.
|
||||
|
||||
## What “best-effort editors” means
|
||||
|
||||
On a coarse-pointer or no-hover device, an editor operation may:
|
||||
|
||||
+6
-1
@@ -55,7 +55,7 @@ override them; a room may override its space; a marker may override its room.
|
||||
| Level | Meaning | Stored data |
|
||||
|---|---|---|
|
||||
| Card | One dashboard instance | Initial space, language, icon size, value/LQI display, live state, kiosk and cycle |
|
||||
| Global settings | Defaults for all spaces | Fill palette, background, Glow radius, north, sun, weather and icon rules |
|
||||
| Global settings | Defaults for all spaces | Fill palette, background, Glow radius, north, sun, room-hover information and icon rules |
|
||||
| Space | Floor, yard, garage or building | Plan image, scale, rooms, walls, openings, decor and display settings |
|
||||
| Room | A closed outline | Name, optional HA area, temperature/humidity source and local fill |
|
||||
| Wall | A room-contour or independent segment | Stable identity and thickness from 0 to 100 cm; zero-thickness appearance is selected per space |
|
||||
@@ -196,6 +196,11 @@ View is the state with no editor open. Close the active editor to return to it.
|
||||
| Kiosk | Actionable as in View | Read-only | Read-only; no editors |
|
||||
| Static card | Not live or interactive | Render only | Render only |
|
||||
|
||||
The room highlight remains available in View and kiosk. To keep that highlight
|
||||
but hide the floating room summary, turn off **General settings → Show the room
|
||||
information window on hover**. The option is on by default and does not affect
|
||||
device tooltips.
|
||||
|
||||
Each editor has a stable primary toolbar. Tool parameters and selected-object
|
||||
actions appear in a context tray over the top of the canvas. On a narrow screen
|
||||
the tray scrolls horizontally instead of shrinking the plan.
|
||||
|
||||
@@ -55,7 +55,7 @@ House Plan — локальная интеграция и две Lovelace-кар
|
||||
| Уровень | Что это | Что хранит |
|
||||
|---|---|---|
|
||||
| Карточка | Один экземпляр `houseplan-card` на дашборде | Стартовое пространство, язык, размер иконок, показ значений/LQI, живые состояния, киоск и автолистание |
|
||||
| Общие настройки | Настройки всего House Plan | Палитры заливок, фон, радиус света, север, солнце, погода, правила иконок |
|
||||
| Общие настройки | Настройки всего House Plan | Палитры заливок, фон, радиус света, север, солнце, окно комнаты при наведении, правила иконок |
|
||||
| Пространство | Этаж, двор, гараж, отдельное строение | Подложку, масштаб сетки, комнаты, стены, проёмы, декор и настройки отображения |
|
||||
| Комната | Только замкнутый контур | Название, необязательную HA-зону, источники температуры/влажности и локальную заливку |
|
||||
| Стена | Сегмент контура комнаты или независимая стена | Стабильный ID и толщину 0–100 см; вид стен нулевой толщины задаётся для пространства |
|
||||
@@ -207,6 +207,11 @@ title: План дома
|
||||
| Киоск | Настенный экран | Интерактивны как в просмотре | Только отображение | Только отображение; редакторы отсутствуют |
|
||||
| Статическая карточка | Компактная схема пространства | Только рисунок | Только рисунок | Без состояний и интерактивности |
|
||||
|
||||
Подсветка комнаты сохраняется в Просмотре и киоске. Чтобы оставить подсветку,
|
||||
но убрать всплывающее описание комнаты, выключите **Общие настройки →
|
||||
Показывать окно с информацией при наведении на комнату**. По умолчанию опция
|
||||
включена и не влияет на подсказки устройств.
|
||||
|
||||
В редакторах сетка продолжается по всему рабочему холсту. В режиме просмотра сетка не показывается.
|
||||
|
||||
Основная панель каждого редактора содержит только постоянные инструменты, а
|
||||
|
||||
@@ -79,6 +79,10 @@ device state do not depend on that gate. A device action that actually dispatche
|
||||
briefly scales its painted shell to 95% and back over 200 ms; informational,
|
||||
editor and no-op paths do not imitate a successful action.
|
||||
|
||||
The global `settings.show_room_tooltip` preference controls only the floating
|
||||
room information window. Missing or invalid values mean enabled; exact `false`
|
||||
hides the window while room highlight and every device tooltip remain active.
|
||||
|
||||
Removed from this mode (they move, not die):
|
||||
- icon dragging ("drag anywhere", v1.9 — consciously reversed),
|
||||
- room-label dragging,
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
backend validation/privacy projection, i18n, документация и QA
|
||||
- **Связи:** #79 (room hover), #154 (pointer modality), #196 (содержимое
|
||||
тултипа)
|
||||
- **Ревизия:** 1 (2026-09-03)
|
||||
- **Ревизия:** 2 (2026-09-03; размещение editor-only строк уточнено по
|
||||
результату bundle-budget без изменения поведения)
|
||||
|
||||
## Сценарий
|
||||
|
||||
@@ -126,7 +127,10 @@ Hover-подсветка уже имеет независимое состоян
|
||||
|
||||
## UX и i18n
|
||||
|
||||
Добавить ключ `gs.show_room_tooltip` во все четыре синхронных словаря:
|
||||
Добавить ключ `gs.show_room_tooltip` во все четыре синхронизированных lazy
|
||||
editor-словаря `src/i18n/support/{en,ru,de,fr}.json`. Существующую editor-only
|
||||
строку `gs.hint` перенести туда же, чтобы новый control не увеличивал initial
|
||||
View graph:
|
||||
|
||||
- RU: `Показывать окно с информацией при наведении на комнату`;
|
||||
- EN: `Show the room information window on hover`;
|
||||
@@ -176,7 +180,7 @@ Hover-подсветка уже имеет независимое состоян
|
||||
|
||||
- `src/types.ts`, `src/logic.ts`, `src/houseplan-card.ts`,
|
||||
`src/houseplan-editor-runtime.ts`.
|
||||
- `src/i18n/{en,ru,de,fr}.json`.
|
||||
- `src/i18n/support/{en,ru,de,fr}.json`, `src/i18n/support.ts`.
|
||||
- `custom_components/houseplan/validation.py`,
|
||||
`custom_components/houseplan/support_package.py`.
|
||||
- `test/logic.test.mjs`, settings/source contract tests,
|
||||
@@ -307,4 +311,3 @@ guard, но backend acceptance/type и support projection временно со
|
||||
- Канонический ключ — `settings.show_room_tooltip`; default хранится отсутствием,
|
||||
а явное значение требуется только для `false`.
|
||||
- `houseplan-space-card` не меняется, потому что уже не имеет интерактивности.
|
||||
|
||||
|
||||
@@ -27,6 +27,13 @@
|
||||
|
||||
/** @type {SmokeLink[]} */
|
||||
export const SMOKE_LINKS = [
|
||||
{
|
||||
symbols: ['showRoomTooltipOf'],
|
||||
smokes: ['smoke_room_tooltip_toggle.mjs'],
|
||||
because: 'the production-bundle scenario proves the global-settings draft and persistence, '
|
||||
+ 'room-only suppression before area work, immediate stale-room-tip cleanup, preserved room '
|
||||
+ 'highlight/device tooltip and default-on restoration (#426)',
|
||||
},
|
||||
{
|
||||
symbols: [
|
||||
'applyDevicePlacement', 'devicePlacement', 'sameDevicePlacement',
|
||||
|
||||
+21
-32
@@ -39,7 +39,7 @@ import {
|
||||
spaceDisplayOf, resolveEffectiveRoomFill, fillColorsOf, DEFAULT_FILL_COLORS,
|
||||
customFillOf, roomCustomFillOf, DEFAULT_CUSTOM_FILL,
|
||||
type FillColors, type FillColorEntry, type ResolvedRoomFill, runServiceFor, RUN_TARGET_DOMAINS,
|
||||
DEFAULT_ROOM_COLOR, DEFAULT_ROOM_OPACITY, stageBgOf,
|
||||
DEFAULT_ROOM_COLOR, DEFAULT_ROOM_OPACITY, stageBgOf, showRoomTooltipOf,
|
||||
DEFAULT_TEMP_MIN, DEFAULT_TEMP_MAX, type SpaceDisplay,
|
||||
referencedContentUrls,
|
||||
DISPLAY_MODES, TAP_ACTIONS, SPACE_FILL_UI_MODES, ROOM_FILL_MODES,
|
||||
@@ -1026,6 +1026,7 @@ export class HouseplanCard extends LitElement {
|
||||
lqi?: number | null;
|
||||
temp?: number | null;
|
||||
hum?: number | null;
|
||||
room?: boolean;
|
||||
} | null = null;
|
||||
/** Room whose physical perimeter is highlighted in View. The explicit
|
||||
* overlay is needed because thick wall bodies paint above room shapes. */
|
||||
@@ -2219,6 +2220,7 @@ export class HouseplanCard extends LitElement {
|
||||
colors: FillColors; glowRadius: number; bgColor: string | null;
|
||||
/** sun on the plan (docs/SUN.md) */
|
||||
northDeg: number | null; bgMode: 'static' | 'daynight'; sunRays: boolean;
|
||||
showRoomTooltip: boolean;
|
||||
busy: boolean;
|
||||
} | null = null;
|
||||
private _supportDialog: SupportDialogState | null = null;
|
||||
@@ -7286,11 +7288,12 @@ export class HouseplanCard extends LitElement {
|
||||
lqi?: number | null,
|
||||
temp?: number | null,
|
||||
hum?: number | null,
|
||||
room = false,
|
||||
): void {
|
||||
this._notePointer(ev);
|
||||
if (!this._pointerModality.hoverEnabled) return;
|
||||
if (this._drag || this._deviceDrag) return;
|
||||
this._tip = { x: ev.clientX, y: ev.clientY, title, meta, lqi, temp, hum };
|
||||
this._tip = { x: ev.clientX, y: ev.clientY, title, meta, lqi, temp, hum, room };
|
||||
}
|
||||
|
||||
// ================= ROOM MARKUP EDITOR =================
|
||||
@@ -11577,6 +11580,10 @@ export class HouseplanCard extends LitElement {
|
||||
let areaText: string | null | undefined;
|
||||
const tip = (e: PointerEvent) => {
|
||||
if (this._mode !== 'view') return;
|
||||
if (!showRoomTooltipOf(this._settings)) {
|
||||
if (this._tip?.room) this._tip = null;
|
||||
return;
|
||||
}
|
||||
if (areaText === undefined) areaText = this._roomArea(r);
|
||||
this._showTip(
|
||||
e,
|
||||
@@ -11585,8 +11592,15 @@ export class HouseplanCard extends LitElement {
|
||||
showLqi ? this._roomLqi(r.area) : null,
|
||||
this._roomTemp(r),
|
||||
this._roomHum(r),
|
||||
true,
|
||||
);
|
||||
};
|
||||
const enterRoom = (event: PointerEvent) => {
|
||||
this._notePointer(event);
|
||||
if (this._pointerModality.hoverEnabled) {
|
||||
this._hoverRoom = { space: space.id, room: r };
|
||||
}
|
||||
};
|
||||
const myPoly = polyOf(r);
|
||||
// A room's ordinary solid stroke must not run beneath its zero
|
||||
// wall overlay — suppress it and draw a trimmed outline. This
|
||||
@@ -11623,57 +11637,32 @@ export class HouseplanCard extends LitElement {
|
||||
? svg`<path class="${cls}" style="${style}" fill-rule="evenodd"
|
||||
data-hp="room" data-id=${hpId} data-area=${hpArea}
|
||||
d="${[obstaclePath, ...holes.map(pathD)].join(' ')}"
|
||||
@pointerenter=${(event: PointerEvent) => {
|
||||
this._notePointer(event);
|
||||
if (this._pointerModality.hoverEnabled) {
|
||||
this._hoverRoom = { space: space.id, room: r };
|
||||
}
|
||||
}}
|
||||
@pointerenter=${enterRoom}
|
||||
@pointermove=${tip}
|
||||
@pointerleave=${() => this._clearTransientHover()}></path>`
|
||||
: holes.length && fillPoly
|
||||
? svg`<path class="${cls}" style="${style}" fill-rule="evenodd"
|
||||
data-hp="room" data-id=${hpId} data-area=${hpArea}
|
||||
d="${[fillPoly, ...holes].map(pathD).join(' ')}"
|
||||
@pointerenter=${(event: PointerEvent) => {
|
||||
this._notePointer(event);
|
||||
if (this._pointerModality.hoverEnabled) {
|
||||
this._hoverRoom = { space: space.id, room: r };
|
||||
}
|
||||
}}
|
||||
@pointerenter=${enterRoom}
|
||||
@pointermove=${tip}
|
||||
@pointerleave=${() => this._clearTransientHover()}></path>`
|
||||
: fillPoly && fillPoly !== myPoly
|
||||
? svg`<polygon class="${cls}" style="${style}" points="${fillPoly.map((p) => p.join(',')).join(' ')}"
|
||||
data-hp="room" data-id=${hpId} data-area=${hpArea}
|
||||
@pointerenter=${(event: PointerEvent) => {
|
||||
this._notePointer(event);
|
||||
if (this._pointerModality.hoverEnabled) {
|
||||
this._hoverRoom = { space: space.id, room: r };
|
||||
}
|
||||
}}
|
||||
@pointerenter=${enterRoom}
|
||||
@pointermove=${tip}
|
||||
@pointerleave=${() => this._clearTransientHover()}></polygon>`
|
||||
: r.poly
|
||||
? svg`<polygon class="${cls}" style="${style}" points="${r.poly.map((p) => p.join(',')).join(' ')}"
|
||||
data-hp="room" data-id=${hpId} data-area=${hpArea}
|
||||
@pointerenter=${(event: PointerEvent) => {
|
||||
this._notePointer(event);
|
||||
if (this._pointerModality.hoverEnabled) {
|
||||
this._hoverRoom = { space: space.id, room: r };
|
||||
}
|
||||
}}
|
||||
@pointerenter=${enterRoom}
|
||||
@pointermove=${tip}
|
||||
@pointerleave=${() => this._clearTransientHover()}></polygon>`
|
||||
: svg`<rect class="${cls}" style="${style}"
|
||||
data-hp="room" data-id=${hpId} data-area=${hpArea}
|
||||
x="${r.x}" y="${r.y}" width="${r.w}" height="${r.h}" rx="${Math.min(r.w!, r.h!) * 0.03}"
|
||||
@pointerenter=${(event: PointerEvent) => {
|
||||
this._notePointer(event);
|
||||
if (this._pointerModality.hoverEnabled) {
|
||||
this._hoverRoom = { space: space.id, room: r };
|
||||
}
|
||||
}}
|
||||
@pointerenter=${enterRoom}
|
||||
@pointermove=${tip}
|
||||
@pointerleave=${() => this._clearTransientHover()}></rect>`;
|
||||
const trimmed = edgeCuts.length && myPoly
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
spaceDisplayOf, resolveEffectiveRoomFill, fillColorsOf, DEFAULT_FILL_COLORS,
|
||||
customFillOf, roomCustomFillOf, DEFAULT_CUSTOM_FILL,
|
||||
type FillColors, type FillColorEntry, type ResolvedRoomFill, runServiceFor, RUN_TARGET_DOMAINS,
|
||||
DEFAULT_ROOM_COLOR, DEFAULT_ROOM_OPACITY, stageBgOf,
|
||||
DEFAULT_ROOM_COLOR, DEFAULT_ROOM_OPACITY, stageBgOf, showRoomTooltipOf,
|
||||
DEFAULT_TEMP_MIN, DEFAULT_TEMP_MAX, type SpaceDisplay,
|
||||
referencedContentUrls,
|
||||
DISPLAY_MODES, TAP_ACTIONS, SPACE_FILL_UI_MODES, ROOM_FILL_MODES,
|
||||
@@ -1112,8 +1112,8 @@ export interface HouseplanEditorHostPort {
|
||||
_sentPos: Map<string, DeviceLayout[string] | null>;
|
||||
_serverCfg: ServerConfig | null;
|
||||
_serverStorage: boolean;
|
||||
_settings: { exclude_integrations?: string[]; group_lights?: boolean; show_all?: boolean; filter_seeded?: boolean; icon_rules?: { pattern: string; icon: string; }[]; };
|
||||
_settingsDialog: { colors: FillColors; glowRadius: number; bgColor: string | null; northDeg: number | null; bgMode: "static" | "daynight"; sunRays: boolean; busy: boolean; } | null;
|
||||
_settings: { exclude_integrations?: string[]; group_lights?: boolean; show_all?: boolean; filter_seeded?: boolean; icon_rules?: { pattern: string; icon: string; }[]; show_room_tooltip?: boolean; };
|
||||
_settingsDialog: { colors: FillColors; glowRadius: number; bgColor: string | null; northDeg: number | null; bgMode: "static" | "daynight"; sunRays: boolean; showRoomTooltip: boolean; busy: boolean; } | null;
|
||||
_supportDialog: SupportDialogState | null;
|
||||
_showAll: boolean;
|
||||
_showHidden: boolean;
|
||||
@@ -1134,7 +1134,7 @@ export interface HouseplanEditorHostPort {
|
||||
_t: (key: I18nKey, vars?: Record<string, string | number>) => string;
|
||||
_undoDevicePosition: () => void;
|
||||
_thickWallCuts: () => number[][];
|
||||
_tip: { x: number; y: number; title: string; meta: string; lqi?: number | null; temp?: number | null; hum?: number | null; } | null;
|
||||
_tip: { x: number; y: number; title: string; meta: string; lqi?: number | null; temp?: number | null; hum?: number | null; room?: boolean; } | null;
|
||||
_toggleConfirmationLines: (intent: ResolvedToggleIntent) => string[];
|
||||
_toggleConfirmationStateText: (target: ResolvedToggleTarget) => string;
|
||||
_toggleIntent: (device: DevItem, devices?: readonly DevItem[]) => ResolvedToggleIntent | null;
|
||||
@@ -9034,6 +9034,7 @@ public _openSettingsDialog = (): void => {
|
||||
northDeg: northDegOf(this.host._settings, {}),
|
||||
bgMode: bgModeOf(this.host._settings, {}),
|
||||
sunRays: sunRaysOn(this.host._settings, {}),
|
||||
showRoomTooltip: showRoomTooltipOf(this.host._settings),
|
||||
busy: false,
|
||||
};
|
||||
};
|
||||
@@ -10233,12 +10234,15 @@ public _updateDecorStyle(next: DecorStyle): void {
|
||||
settings.bg_mode = d.bgMode;
|
||||
if (d.sunRays) settings.sun_rays = true;
|
||||
else delete settings.sun_rays;
|
||||
if (d.showRoomTooltip) delete settings.show_room_tooltip;
|
||||
else settings.show_room_tooltip = false;
|
||||
// Legacy compatibility: old configs may still contain this accepted
|
||||
// field, but weather no longer affects sunlight and the UI no longer
|
||||
// exposes it. Saving general settings cleans the obsolete value up.
|
||||
delete settings.weather_entity;
|
||||
this.host._serverCfg = { ...cfg, settings };
|
||||
await this._saveConfigNow();
|
||||
if (!d.showRoomTooltip && this.host._tip?.room) this.host._tip = null;
|
||||
this.host._settingsDialog = null;
|
||||
this.host.requestUpdate();
|
||||
this.host._showToast(this.host._t('gs.saved'));
|
||||
@@ -10534,7 +10538,16 @@ public _renderSettingsDialog(): TemplateResult {
|
||||
return html`<hp-dialog .hass=${this.host.hass} .title=${this.host._t('gs.title')} icon="mdi:cog-outline" wide
|
||||
@hp-close=${() => (this.host._settingsDialog = null)}>
|
||||
<div class="body">
|
||||
<div class="rhint">${this.host._t('gs.hint')}</div>
|
||||
<div class="rhint">${supportT(
|
||||
langOf(this.host.hass, this.host._config?.language), 'gs.hint',
|
||||
)}</div>
|
||||
<label class="srcrow">
|
||||
${this._boolInput(this.host._settingsDialog!.showRoomTooltip, (v) =>
|
||||
(this.host._settingsDialog = { ...this.host._settingsDialog!, showRoomTooltip: v }))}
|
||||
<span>${supportT(
|
||||
langOf(this.host.hass, this.host._config?.language), 'gs.show_room_tooltip',
|
||||
)}</span>
|
||||
</label>
|
||||
<label class="dispsection">${this.host._t('gs.light_group')}</label>
|
||||
${this._renderColorRow('light_on', 'gs.light_on')}
|
||||
${this._renderColorRow('light_off', 'gs.light_off')}
|
||||
@@ -10660,7 +10673,7 @@ public _renderSettingsDialog(): TemplateResult {
|
||||
</div>
|
||||
<div class="row" slot="footer">
|
||||
<button class="btn ghost" @click=${() =>
|
||||
(this.host._settingsDialog = { ...this.host._settingsDialog!, colors: JSON.parse(JSON.stringify(DEFAULT_FILL_COLORS)), glowRadius: this.host._imperial ? 9.8 : 3, bgColor: null, northDeg: null, bgMode: 'daynight', sunRays: false })}>
|
||||
(this.host._settingsDialog = { ...this.host._settingsDialog!, colors: JSON.parse(JSON.stringify(DEFAULT_FILL_COLORS)), glowRadius: this.host._imperial ? 9.8 : 3, bgColor: null, northDeg: null, bgMode: 'daynight', sunRays: false, showRoomTooltip: true })}>
|
||||
${this.host._t('gs.reset')}
|
||||
</button>
|
||||
<span class="spacer"></span>
|
||||
|
||||
@@ -422,7 +422,6 @@
|
||||
"marker.sub_entity": "Entität",
|
||||
"title.general_settings": "Allgemeine Einstellungen",
|
||||
"gs.title": "Allgemeine Einstellungen",
|
||||
"gs.hint": "Füllfarben gelten für jeden Bereich; jede Farbe hat ihre eigene Deckkraft. Der Füllmodus wird in den Einstellungen des jeweiligen Bereichs festgelegt.",
|
||||
"gs.light_group": "Füllung: Licht",
|
||||
"gs.light_on": "Lichter an",
|
||||
"gs.light_off": "Alle Lichter aus",
|
||||
|
||||
@@ -422,7 +422,6 @@
|
||||
"marker.sub_entity": "entity",
|
||||
"title.general_settings": "General settings",
|
||||
"gs.title": "General settings",
|
||||
"gs.hint": "Fill colors apply to every space; each color has its own opacity. Which fill mode a space uses is set in that space's dialog.",
|
||||
"gs.light_group": "Fill: lights",
|
||||
"gs.light_on": "Lights on",
|
||||
"gs.light_off": "All lights off",
|
||||
|
||||
@@ -422,7 +422,6 @@
|
||||
"marker.sub_entity": "entité",
|
||||
"title.general_settings": "Paramètres généraux",
|
||||
"gs.title": "Paramètres généraux",
|
||||
"gs.hint": "Les couleurs de remplissage s’appliquent à tous les espaces ; chaque couleur possède sa propre opacité. Le mode de remplissage utilisé par un espace se règle dans la boîte de dialogue de cet espace.",
|
||||
"gs.light_group": "Remplissage : lumières",
|
||||
"gs.light_on": "Lumières allumées",
|
||||
"gs.light_off": "Toutes les lumières éteintes",
|
||||
|
||||
@@ -422,7 +422,6 @@
|
||||
"marker.sub_entity": "сущность",
|
||||
"title.general_settings": "Общие настройки",
|
||||
"gs.title": "Общие настройки",
|
||||
"gs.hint": "Цвета заливок действуют на все пространства; у каждого цвета своя прозрачность. Какой режим заливки использует пространство — задаётся в его диалоге.",
|
||||
"gs.light_group": "Заливка: освещение",
|
||||
"gs.light_on": "Свет включён",
|
||||
"gs.light_off": "Весь свет выключен",
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
/** Lazy Help & feedback dictionaries owned by the editor runtime (#423). */
|
||||
/** Lazy editor-only dictionaries owned by the editor runtime (#423). */
|
||||
import { subst } from '../logic';
|
||||
import type { Lang } from './registry';
|
||||
import de from './support/de.json' with { type: 'json' };
|
||||
@@ -15,7 +15,7 @@ const SUPPORT_DICTIONARIES: Record<Lang, Record<SupportI18nKey, string>> = {
|
||||
fr,
|
||||
};
|
||||
|
||||
/** Translate form-only support copy with the same synchronous English fallback. */
|
||||
/** Translate editor-only copy with the same synchronous English fallback. */
|
||||
export function supportT(
|
||||
lang: Lang,
|
||||
key: SupportI18nKey,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"gs.hint": "Füllfarben gelten für jeden Bereich; jede Farbe hat ihre eigene Deckkraft. Der Füllmodus wird in den Einstellungen des jeweiligen Bereichs festgelegt.",
|
||||
"gs.show_room_tooltip": "Rauminformationen beim Darüberfahren anzeigen",
|
||||
"support.about_group": "Über die Karte",
|
||||
"support.guide_group": "Dokumentation",
|
||||
"support.guide": "Benutzerhandbuch",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"gs.hint": "Fill colors apply to every space; each color has its own opacity. Which fill mode a space uses is set in that space's dialog.",
|
||||
"gs.show_room_tooltip": "Show the room information window on hover",
|
||||
"support.about_group": "About the card",
|
||||
"support.guide_group": "Documentation",
|
||||
"support.guide": "User guide",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"gs.hint": "Les couleurs de remplissage s’appliquent à tous les espaces ; chaque couleur possède sa propre opacité. Le mode de remplissage utilisé par un espace se règle dans la boîte de dialogue de cet espace.",
|
||||
"gs.show_room_tooltip": "Afficher les informations de la pièce au survol",
|
||||
"support.about_group": "À propos de la carte",
|
||||
"support.guide_group": "Documentation d’aide",
|
||||
"support.guide": "Guide utilisateur",
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
{
|
||||
"gs.hint": "Цвета заливок действуют на все пространства; у каждого цвета своя прозрачность. Какой режим заливки использует пространство — задаётся в его диалоге.",
|
||||
"gs.show_room_tooltip": "Показывать окно с информацией при наведении на комнату",
|
||||
"support.about_group": "О карточке",
|
||||
"support.guide_group": "Документация",
|
||||
"support.guide": "Руководство пользователя",
|
||||
|
||||
@@ -1351,6 +1351,13 @@ export function stageBgOf(settings: any, disp: { bgColor: string | null }): stri
|
||||
return safeStoredColor(g, '');
|
||||
}
|
||||
|
||||
/** Global room-hover information preference. Legacy and malformed values keep
|
||||
* the historical default; only an explicit boolean false disables the window. */
|
||||
export function showRoomTooltipOf(settings: unknown): boolean {
|
||||
return (settings as { show_room_tooltip?: unknown } | null | undefined)
|
||||
?.show_room_tooltip !== false;
|
||||
}
|
||||
|
||||
// ---------------- global fill colors ----------------
|
||||
|
||||
export interface FillColorEntry {
|
||||
|
||||
@@ -247,6 +247,8 @@ export interface ServerConfig {
|
||||
/** Internal registry-Area provenance; not a user-facing setting. */
|
||||
marker_area_snapshot?: MarkerAreaSnapshot;
|
||||
icon_rules?: { pattern: string; icon: string }[];
|
||||
/** Only an explicit false hides the room hover information window. */
|
||||
show_room_tooltip?: boolean;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -126,11 +126,11 @@ test('i18n: every registered dictionary carries the English key set', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('i18n: lazy support dictionaries carry matching keys and placeholders', () => {
|
||||
test('i18n: lazy editor dictionaries carry matching keys and placeholders', () => {
|
||||
const supportEn = supportDictionaries.get('en');
|
||||
const keys = Object.keys(supportEn).sort();
|
||||
const placeholders = (value) => (String(value).match(/\{\w+\}/gu) || []).sort();
|
||||
assert.equal(keys.length, 42);
|
||||
assert.equal(keys.length, 44);
|
||||
assert.equal(Object.keys(en).filter((key) => key.startsWith('support.')).join(','), 'support.title');
|
||||
for (const { code } of LANGUAGE_REGISTRY) {
|
||||
const dictionary = supportDictionaries.get(code);
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
hassValue, valueWithUnit, decorTextScale, decorTextLines,
|
||||
LIVE_TEXT_DASH, LIVE_TEXT_VALUE_MAX, DECOR_TEXT_SCALE_MIN, DECOR_TEXT_SCALE_MAX,
|
||||
quantizeOpeningLightAmount,
|
||||
showRoomTooltipOf,
|
||||
} from '../test-build/logic.js';
|
||||
import {
|
||||
iconFor, compileIconRules, isValidPattern, iconFromDeviceClasses,
|
||||
@@ -35,6 +36,17 @@ test('tap action editor choices keep the canonical order', () => {
|
||||
assert.deepEqual([...TAP_ACTIONS], ['info', 'more-info', 'toggle', 'run', 'none']);
|
||||
});
|
||||
|
||||
test('room tooltip preference is default-on and only exact false disables it', () => {
|
||||
for (const value of [undefined, null, true, 0, 1, 'false', [], {}]) {
|
||||
assert.equal(showRoomTooltipOf(value), true);
|
||||
}
|
||||
assert.equal(showRoomTooltipOf({ show_room_tooltip: undefined }), true);
|
||||
assert.equal(showRoomTooltipOf({ show_room_tooltip: null }), true);
|
||||
assert.equal(showRoomTooltipOf({ show_room_tooltip: true }), true);
|
||||
assert.equal(showRoomTooltipOf({ show_room_tooltip: 'false' }), true);
|
||||
assert.equal(showRoomTooltipOf({ show_room_tooltip: false }), false);
|
||||
});
|
||||
|
||||
test('display normalization and alarm-capable metadata share one contract', () => {
|
||||
assert.equal(normalizeDeviceDisplay(undefined), 'badge');
|
||||
assert.equal(normalizeDeviceDisplay('ripple'), 'icon_ripple');
|
||||
|
||||
@@ -200,6 +200,7 @@ def test_rich_plan_projection_preserves_safe_structure_and_drops_unknown_values(
|
||||
"model_version": 9,
|
||||
"settings": {
|
||||
"north_deg": 30,
|
||||
"show_room_tooltip": False,
|
||||
"fill_colors": {"warm": {"c": "#ffaa00", "a": 0.5, "secret": "drop"}},
|
||||
"decor_default_style": {
|
||||
"color": "#123456", "width_cm": 2, "secret": "drop",
|
||||
@@ -290,6 +291,7 @@ def test_rich_plan_projection_preserves_safe_structure_and_drops_unknown_values(
|
||||
|
||||
assert package["versions"]["card"] == "unknown"
|
||||
assert plan["settings"]["fill_colors"] == {"warm": {"a": 0.5, "c": "#ffaa00"}}
|
||||
assert plan["settings"]["show_room_tooltip"] is False
|
||||
assert plan["settings"]["decor_default_style"] == {"color": "#123456", "width_cm": 2}
|
||||
assert space["rooms"][0]["poly"] == [[0, 0], [2, 0]]
|
||||
assert space["rooms"][0]["settings"]["temp_source_kind"] == "entity"
|
||||
@@ -334,6 +336,7 @@ def test_projection_helpers_fail_closed_on_malformed_shapes():
|
||||
assert support_package._points(None) == []
|
||||
assert support_package._custom_fill(None) is None
|
||||
assert support_package._global_settings(None) == {}
|
||||
assert support_package._global_settings({"show_room_tooltip": "false"}) == {}
|
||||
assert support_package._room_settings(ids, None) == {}
|
||||
assert support_package._project_layout(ids, None) == {}
|
||||
assert support_package._summary(None, None)["spaces"] == 0
|
||||
|
||||
@@ -479,6 +479,19 @@ def test_sun_settings_global():
|
||||
v.CONFIG_SCHEMA({"spaces": [], "settings": {"weather_entity": {"e": 1}}})
|
||||
|
||||
|
||||
def test_room_tooltip_global_setting_is_strict_boolean_and_round_trips():
|
||||
for value in (True, False):
|
||||
out = v.CONFIG_SCHEMA(
|
||||
{"spaces": [], "settings": {"show_room_tooltip": value}}
|
||||
)
|
||||
assert out["settings"]["show_room_tooltip"] is value
|
||||
for bad in (None, 0, 1, "false", [], {}):
|
||||
with pytest.raises(vol.Invalid):
|
||||
v.CONFIG_SCHEMA(
|
||||
{"spaces": [], "settings": {"show_room_tooltip": bad}}
|
||||
)
|
||||
|
||||
|
||||
def test_marker_area_snapshot_is_strict_and_bounded():
|
||||
"""#126: Area provenance accepts only exact direct bindings and non-empty Areas."""
|
||||
snapshot = {
|
||||
|
||||
Reference in New Issue
Block a user