mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-01 12:18:51 +00:00
@@ -1,125 +1,125 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "c3f3b28b3149752a2b63584dbe161b2a247db77770fd5bd84bd87a14f303b3a6",
|
||||
"fingerprint": "86bca8107c5d9e57b05a46242a839b6a888240ff8560cc296275e39dbc668668",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js",
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 290566,
|
||||
"initialViewGzipBytes": 290568,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/de-Bja91KNY.js",
|
||||
"houseplan-assets/editor-CMVCfgT3.js",
|
||||
"houseplan-assets/fr-ClzwnAMY.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BSYUK6nC.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B9wPxaO1.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/de-Co7h1A4k.js",
|
||||
"houseplan-assets/editor-kfbSO1xJ.js",
|
||||
"houseplan-assets/fr-BOp29Mo4.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Dy3ho_PX.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-BuI5u78M.js"
|
||||
],
|
||||
"lazyGzipBytes": 205825,
|
||||
"lazyGzipBytes": 206073,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/editor-CMVCfgT3.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BSYUK6nC.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/editor-kfbSO1xJ.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Dy3ho_PX.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 148718,
|
||||
"lazyEditorGzipBytes": 148958,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B9wPxaO1.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-BuI5u78M.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 14032,
|
||||
"lazyOnboardingGzipBytes": 14030,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-Bja91KNY.js",
|
||||
"houseplan-assets/fr-ClzwnAMY.js"
|
||||
"houseplan-assets/de-Co7h1A4k.js",
|
||||
"houseplan-assets/fr-BOp29Mo4.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 50147,
|
||||
"lazyLocaleGzipBytes": 50156,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"sha256": "5dfc1f1a537f2026f2b2e0628bde0dde81e62278f9fd07647b748a334af220ac",
|
||||
"path": "houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"sha256": "d686cf21b2714cb7a0b6a6992ae111135b5ec6f344aba7045ce92f865614917d",
|
||||
"rawBytes": 20636,
|
||||
"gzipBytes": 7072,
|
||||
"gzipBytes": 7071,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-Bja91KNY.js",
|
||||
"sha256": "62fc9d40d1de845df4c83a527d1426b927c7b87b2a83da8271e14485edebca51",
|
||||
"path": "houseplan-assets/de-Co7h1A4k.js",
|
||||
"sha256": "7d508bfc2ac62d6b554a17455710be751291867a02f158d7af33868c57b8ea9a",
|
||||
"rawBytes": 83981,
|
||||
"gzipBytes": 25344,
|
||||
"gzipBytes": 25349,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-CMVCfgT3.js",
|
||||
"sha256": "408f5bc440896e6b29eaf3ab59d30960974215e3d0341161675a3e88a8f2700e",
|
||||
"path": "houseplan-assets/editor-kfbSO1xJ.js",
|
||||
"sha256": "a515e5da0e979ac670a06aeff4eda8645b5508484666b902deb21cc91eab2eaa",
|
||||
"rawBytes": 3826,
|
||||
"gzipBytes": 1583,
|
||||
"gzipBytes": 1580,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-ClzwnAMY.js",
|
||||
"sha256": "976d7e2294ffccbd4223e2ffba4b5c43697edbb8e1baa37d6b785f6a98c69bcc",
|
||||
"path": "houseplan-assets/fr-BOp29Mo4.js",
|
||||
"sha256": "925c012768c6fff20143c0dc23e28272a9237eb2cfe316c0a845a9ef836163d6",
|
||||
"rawBytes": 86212,
|
||||
"gzipBytes": 24803,
|
||||
"gzipBytes": 24807,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-DoTfrXZx.js",
|
||||
"sha256": "40cc6422072c6017550b0cbf73a772ae4839e172d1187510f1eb92dd78ccb1d5",
|
||||
"path": "houseplan-assets/houseplan-card-tbclbSeu.js",
|
||||
"sha256": "5a2ef33b7b2fee90a86909f9112ed4426634bb92539c36fb6492415e5971984d",
|
||||
"rawBytes": 1032986,
|
||||
"gzipBytes": 289769,
|
||||
"gzipBytes": 289772,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-Bja91KNY.js",
|
||||
"houseplan-assets/editor-CMVCfgT3.js",
|
||||
"houseplan-assets/fr-ClzwnAMY.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BSYUK6nC.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B9wPxaO1.js"
|
||||
"houseplan-assets/de-Co7h1A4k.js",
|
||||
"houseplan-assets/editor-kfbSO1xJ.js",
|
||||
"houseplan-assets/fr-BOp29Mo4.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Dy3ho_PX.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-BuI5u78M.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-BSYUK6nC.js",
|
||||
"sha256": "9d86b76630217ad0b95a8f9f5b3ee8c04776f3450f911b3d24eb5c0d6170e10b",
|
||||
"rawBytes": 543265,
|
||||
"gzipBytes": 140063,
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-Dy3ho_PX.js",
|
||||
"sha256": "b7924f294dab05b23b3cccb6201ed69a48498eb603e965493c13fdaf96c5b9fa",
|
||||
"rawBytes": 544110,
|
||||
"gzipBytes": 140307,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-B9wPxaO1.js",
|
||||
"sha256": "9e5fb7f22b8a9fba1afd1e5930b8da2e1250a55aac7610d60061d9cb80aa9091",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-BuI5u78M.js",
|
||||
"sha256": "a7e139c1110cbfba8df39dd8010508fd5120cb734fd33873e15264b031149882",
|
||||
"rawBytes": 28088,
|
||||
"gzipBytes": 6960,
|
||||
"gzipBytes": 6959,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "9e0f7a84c95cc7aec1c4e3e20e3a8663e12f418a089e3897dcac67fa1be94ae0",
|
||||
"sha256": "5aeb63b7e05cd86436a5e97e91ca00e27b943fcc2475dee490b21902f5ff23bb",
|
||||
"rawBytes": 1183,
|
||||
"gzipBytes": 797,
|
||||
"gzipBytes": 796,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c3f3b28b3149752a2b63584dbe161b2a247db77770fd5bd84bd87a14f303b3a6";import{b as e,l as o,t,d8 as s,A as a,d9 as i,da as l,db as n,E as r,c}from"./houseplan-card-DoTfrXZx.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
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="86bca8107c5d9e57b05a46242a839b6a888240ff8560cc296275e39dbc668668";import{b as e,l as o,t,d8 as s,A as a,d9 as i,da as l,db as n,E as r,c}from"./houseplan-card-tbclbSeu.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}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
+3
-3
File diff suppressed because one or more lines are too long
+28
-28
File diff suppressed because one or more lines are too long
+7
-7
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c3f3b28b3149752a2b63584dbe161b2a247db77770fd5bd84bd87a14f303b3a6";try{await import("./houseplan-assets/houseplan-card-DoTfrXZx.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__="86bca8107c5d9e57b05a46242a839b6a888240ff8560cc296275e39dbc668668";try{await import("./houseplan-assets/houseplan-card-tbclbSeu.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)}
|
||||
|
||||
+124
-10
@@ -46,6 +46,19 @@ const result = await page.evaluate(async ({ version, previewText, previewSha })
|
||||
const originalCallWS = card.hass.callWS.bind(card.hass);
|
||||
const calls = [];
|
||||
let submitMode = 'success';
|
||||
let previewToken = 'a';
|
||||
let deferPreviews = false;
|
||||
const pendingPreviews = [];
|
||||
const previewPayload = (tokenChar = previewToken) => ({
|
||||
text: previewText,
|
||||
size: new TextEncoder().encode(previewText).byteLength,
|
||||
expires_in: 300,
|
||||
spaces: 2,
|
||||
token: tokenChar.repeat(48),
|
||||
sha256: previewSha,
|
||||
version: 1,
|
||||
format: 'houseplan-support-package',
|
||||
});
|
||||
card.hass = {
|
||||
...card.hass,
|
||||
callWS: async (message) => {
|
||||
@@ -54,16 +67,10 @@ const result = await page.evaluate(async ({ version, previewText, previewSha })
|
||||
}
|
||||
calls.push(structuredClone(message));
|
||||
if (message.type === 'houseplan/support/preview') {
|
||||
return {
|
||||
text: previewText,
|
||||
size: new TextEncoder().encode(previewText).byteLength,
|
||||
expires_in: 300,
|
||||
spaces: 2,
|
||||
token: 'a'.repeat(48),
|
||||
sha256: previewSha,
|
||||
version: 1,
|
||||
format: 'houseplan-support-package',
|
||||
};
|
||||
if (deferPreviews) {
|
||||
return new Promise((resolve, reject) => pendingPreviews.push({ resolve, reject }));
|
||||
}
|
||||
return previewPayload();
|
||||
}
|
||||
if (message.type === 'houseplan/support/submit') {
|
||||
if (submitMode === 'rate') throw { code: 'support_rate_limited' };
|
||||
@@ -244,6 +251,113 @@ const result = await page.evaluate(async ({ version, previewText, previewSha })
|
||||
&& retryRequests.every((call) => call.idempotency_key === retryKey)
|
||||
&& root().querySelector('#support-receipt')?.textContent.includes('HP-43-SMOKE') === true;
|
||||
|
||||
await close();
|
||||
await open();
|
||||
deferPreviews = true;
|
||||
const canceledBuild = card._editorRuntime._setSupportAttachment(true);
|
||||
await until(() => pendingPreviews.length === 1
|
||||
&& card._supportDialog?.status === 'building', 'deferred preview building');
|
||||
await update();
|
||||
const disabledWhileBuilding = root().querySelector('.supportattach input')?.disabled === true;
|
||||
const canceledRequest = pendingPreviews.shift();
|
||||
await card._editorRuntime._setSupportAttachment(false);
|
||||
await update();
|
||||
const hiddenImmediately = card._supportDialog?.attach === false
|
||||
&& card._supportDialog?.status === 'idle'
|
||||
&& card._supportDialog?.preview === null
|
||||
&& !root().querySelector('.supportpreview');
|
||||
canceledRequest.resolve(previewPayload('b'));
|
||||
await canceledBuild;
|
||||
await update();
|
||||
const discardedB = calls.filter((call) => call.type === 'houseplan/support/preview/discard'
|
||||
&& call.token === 'b'.repeat(48)).length;
|
||||
out.latePreviewConsentStaysRevoked = disabledWhileBuilding && hiddenImmediately
|
||||
&& card._supportDialog?.attach === false
|
||||
&& card._supportDialog?.status === 'idle'
|
||||
&& card._supportDialog?.preview === null
|
||||
&& !root().querySelector('.supportpreview')
|
||||
&& discardedB === 1;
|
||||
|
||||
const oldBuild = card._editorRuntime._setSupportAttachment(true);
|
||||
await until(() => pendingPreviews.length === 1, 'old preview queued');
|
||||
const oldRequest = pendingPreviews.shift();
|
||||
await card._editorRuntime._setSupportAttachment(false);
|
||||
const latestBuild = card._editorRuntime._setSupportAttachment(true);
|
||||
await until(() => pendingPreviews.length === 1, 'latest preview queued');
|
||||
const latestRequest = pendingPreviews.shift();
|
||||
latestRequest.resolve(previewPayload('c'));
|
||||
await latestBuild;
|
||||
oldRequest.resolve(previewPayload('d'));
|
||||
await oldBuild;
|
||||
await update();
|
||||
out.latestPreviewGenerationWins = card._supportDialog?.attach === true
|
||||
&& card._supportDialog?.status === 'ready'
|
||||
&& card._supportDialog?.preview?.token === 'c'.repeat(48)
|
||||
&& calls.filter((call) => call.type === 'houseplan/support/preview/discard'
|
||||
&& call.token === 'd'.repeat(48)).length === 1;
|
||||
|
||||
const rejectedBuild = card._editorRuntime._refreshSupportPreview();
|
||||
await until(() => pendingPreviews.length === 1
|
||||
&& card._supportDialog?.status === 'building', 'rejected stale preview queued');
|
||||
const rejectedRequest = pendingPreviews.shift();
|
||||
await card._editorRuntime._setSupportAttachment(false);
|
||||
rejectedRequest.reject({ code: 'support_rejected' });
|
||||
await rejectedBuild;
|
||||
await update();
|
||||
out.stalePreviewErrorIsIgnored = card._supportDialog?.attach === false
|
||||
&& card._supportDialog?.status === 'idle'
|
||||
&& card._supportDialog?.errorCode === ''
|
||||
&& card._supportDialog?.preview === null
|
||||
&& !root().querySelector('.supportpreview');
|
||||
deferPreviews = false;
|
||||
|
||||
await close();
|
||||
await open();
|
||||
const validationKey = card._supportDialog.idempotencyKey;
|
||||
const submitsBeforeEmptyValidation = calls.filter(
|
||||
(call) => call.type === 'houseplan/support/submit',
|
||||
).length;
|
||||
await card._editorRuntime._submitSupport();
|
||||
await update();
|
||||
out.validationDoesNotRotateKey = card._supportDialog?.idempotencyKey === validationKey
|
||||
&& card._supportDialog?.submissionFingerprint === ''
|
||||
&& calls.filter((call) => call.type === 'houseplan/support/submit').length
|
||||
=== submitsBeforeEmptyValidation;
|
||||
|
||||
const failSubmit = async () => {
|
||||
await card._editorRuntime._submitSupport();
|
||||
await until(() => card._supportDialog?.status === 'error', 'payload submit failure');
|
||||
await update();
|
||||
return calls.findLast((call) => call.type === 'houseplan/support/submit');
|
||||
};
|
||||
submitMode = 'rate';
|
||||
await setInput('#support-message', ' First payload ');
|
||||
const firstPayloadRequest = await failSubmit();
|
||||
await setInput('#support-message', 'First payload ');
|
||||
const trimOnlyRequest = await failSubmit();
|
||||
await setInput('#support-message', 'Second payload');
|
||||
const changedMessageRequest = await failSubmit();
|
||||
await setInput('#support-contact', 'owner@example.test');
|
||||
const changedContactRequest = await failSubmit();
|
||||
previewToken = 'e';
|
||||
await card._editorRuntime._setSupportAttachment(true);
|
||||
const attachedRequest = await failSubmit();
|
||||
await card._editorRuntime._setSupportAttachment(false);
|
||||
previewToken = 'f';
|
||||
await card._editorRuntime._setSupportAttachment(true);
|
||||
const changedPreviewRequest = await failSubmit();
|
||||
out.idempotencyKeyFollowsEffectivePayload = firstPayloadRequest?.idempotency_key === validationKey
|
||||
&& trimOnlyRequest?.idempotency_key === firstPayloadRequest?.idempotency_key
|
||||
&& changedMessageRequest?.idempotency_key !== trimOnlyRequest?.idempotency_key
|
||||
&& changedContactRequest?.idempotency_key !== changedMessageRequest?.idempotency_key
|
||||
&& attachedRequest?.idempotency_key !== changedContactRequest?.idempotency_key
|
||||
&& attachedRequest?.preview_token === 'e'.repeat(48)
|
||||
&& changedPreviewRequest?.idempotency_key !== attachedRequest?.idempotency_key
|
||||
&& changedPreviewRequest?.preview_token === 'f'.repeat(48)
|
||||
&& firstPayloadRequest?.message === 'First payload'
|
||||
&& firstPayloadRequest?.contact === '';
|
||||
await close();
|
||||
|
||||
return out;
|
||||
}, { version: VERSION, previewText: PREVIEW_TEXT, previewSha: PREVIEW_SHA });
|
||||
|
||||
|
||||
Vendored
+56
-56
@@ -1,125 +1,125 @@
|
||||
{
|
||||
"schema": 1,
|
||||
"fingerprint": "c3f3b28b3149752a2b63584dbe161b2a247db77770fd5bd84bd87a14f303b3a6",
|
||||
"fingerprint": "86bca8107c5d9e57b05a46242a839b6a888240ff8560cc296275e39dbc668668",
|
||||
"entry": "houseplan-card.js",
|
||||
"initialViewFiles": [
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js",
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js",
|
||||
"houseplan-card.js"
|
||||
],
|
||||
"initialViewGzipBytes": 290566,
|
||||
"initialViewGzipBytes": 290568,
|
||||
"lazyFiles": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/de-Bja91KNY.js",
|
||||
"houseplan-assets/editor-CMVCfgT3.js",
|
||||
"houseplan-assets/fr-ClzwnAMY.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BSYUK6nC.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B9wPxaO1.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/de-Co7h1A4k.js",
|
||||
"houseplan-assets/editor-kfbSO1xJ.js",
|
||||
"houseplan-assets/fr-BOp29Mo4.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Dy3ho_PX.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-BuI5u78M.js"
|
||||
],
|
||||
"lazyGzipBytes": 205825,
|
||||
"lazyGzipBytes": 206073,
|
||||
"lazyEditorFiles": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/editor-CMVCfgT3.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BSYUK6nC.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/editor-kfbSO1xJ.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Dy3ho_PX.js"
|
||||
],
|
||||
"lazyEditorGzipBytes": 148718,
|
||||
"lazyEditorGzipBytes": 148958,
|
||||
"lazyOnboardingFiles": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B9wPxaO1.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-BuI5u78M.js"
|
||||
],
|
||||
"lazyOnboardingGzipBytes": 14032,
|
||||
"lazyOnboardingGzipBytes": 14030,
|
||||
"lazyLocaleFiles": [
|
||||
"houseplan-assets/de-Bja91KNY.js",
|
||||
"houseplan-assets/fr-ClzwnAMY.js"
|
||||
"houseplan-assets/de-Co7h1A4k.js",
|
||||
"houseplan-assets/fr-BOp29Mo4.js"
|
||||
],
|
||||
"lazyLocaleGzipBytes": 50147,
|
||||
"lazyLocaleGzipBytes": 50156,
|
||||
"files": [
|
||||
{
|
||||
"path": "houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"sha256": "5dfc1f1a537f2026f2b2e0628bde0dde81e62278f9fd07647b748a334af220ac",
|
||||
"path": "houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"sha256": "d686cf21b2714cb7a0b6a6992ae111135b5ec6f344aba7045ce92f865614917d",
|
||||
"rawBytes": 20636,
|
||||
"gzipBytes": 7072,
|
||||
"gzipBytes": 7071,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/de-Bja91KNY.js",
|
||||
"sha256": "62fc9d40d1de845df4c83a527d1426b927c7b87b2a83da8271e14485edebca51",
|
||||
"path": "houseplan-assets/de-Co7h1A4k.js",
|
||||
"sha256": "7d508bfc2ac62d6b554a17455710be751291867a02f158d7af33868c57b8ea9a",
|
||||
"rawBytes": 83981,
|
||||
"gzipBytes": 25344,
|
||||
"gzipBytes": 25349,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/editor-CMVCfgT3.js",
|
||||
"sha256": "408f5bc440896e6b29eaf3ab59d30960974215e3d0341161675a3e88a8f2700e",
|
||||
"path": "houseplan-assets/editor-kfbSO1xJ.js",
|
||||
"sha256": "a515e5da0e979ac670a06aeff4eda8645b5508484666b902deb21cc91eab2eaa",
|
||||
"rawBytes": 3826,
|
||||
"gzipBytes": 1583,
|
||||
"gzipBytes": 1580,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/fr-ClzwnAMY.js",
|
||||
"sha256": "976d7e2294ffccbd4223e2ffba4b5c43697edbb8e1baa37d6b785f6a98c69bcc",
|
||||
"path": "houseplan-assets/fr-BOp29Mo4.js",
|
||||
"sha256": "925c012768c6fff20143c0dc23e28272a9237eb2cfe316c0a845a9ef836163d6",
|
||||
"rawBytes": 86212,
|
||||
"gzipBytes": 24803,
|
||||
"gzipBytes": 24807,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-card-DoTfrXZx.js",
|
||||
"sha256": "40cc6422072c6017550b0cbf73a772ae4839e172d1187510f1eb92dd78ccb1d5",
|
||||
"path": "houseplan-assets/houseplan-card-tbclbSeu.js",
|
||||
"sha256": "5a2ef33b7b2fee90a86909f9112ed4426634bb92539c36fb6492415e5971984d",
|
||||
"rawBytes": 1032986,
|
||||
"gzipBytes": 289769,
|
||||
"gzipBytes": 289772,
|
||||
"isEntry": false,
|
||||
"imports": [],
|
||||
"dynamicImports": [
|
||||
"houseplan-assets/de-Bja91KNY.js",
|
||||
"houseplan-assets/editor-CMVCfgT3.js",
|
||||
"houseplan-assets/fr-ClzwnAMY.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-BSYUK6nC.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-B9wPxaO1.js"
|
||||
"houseplan-assets/de-Co7h1A4k.js",
|
||||
"houseplan-assets/editor-kfbSO1xJ.js",
|
||||
"houseplan-assets/fr-BOp29Mo4.js",
|
||||
"houseplan-assets/houseplan-editor-runtime-Dy3ho_PX.js",
|
||||
"houseplan-assets/houseplan-onboarding-runtime-BuI5u78M.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-BSYUK6nC.js",
|
||||
"sha256": "9d86b76630217ad0b95a8f9f5b3ee8c04776f3450f911b3d24eb5c0d6170e10b",
|
||||
"rawBytes": 543265,
|
||||
"gzipBytes": 140063,
|
||||
"path": "houseplan-assets/houseplan-editor-runtime-Dy3ho_PX.js",
|
||||
"sha256": "b7924f294dab05b23b3cccb6201ed69a48498eb603e965493c13fdaf96c5b9fa",
|
||||
"rawBytes": 544110,
|
||||
"gzipBytes": 140307,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-B9wPxaO1.js",
|
||||
"sha256": "9e5fb7f22b8a9fba1afd1e5930b8da2e1250a55aac7610d60061d9cb80aa9091",
|
||||
"path": "houseplan-assets/houseplan-onboarding-runtime-BuI5u78M.js",
|
||||
"sha256": "a7e139c1110cbfba8df39dd8010508fd5120cb734fd33873e15264b031149882",
|
||||
"rawBytes": 28088,
|
||||
"gzipBytes": 6960,
|
||||
"gzipBytes": 6959,
|
||||
"isEntry": false,
|
||||
"imports": [
|
||||
"houseplan-assets/backdrop-pick-CrHBqjf1.js",
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/backdrop-pick-B0-0LPJ7.js",
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
},
|
||||
{
|
||||
"path": "houseplan-card.js",
|
||||
"sha256": "9e0f7a84c95cc7aec1c4e3e20e3a8663e12f418a089e3897dcac67fa1be94ae0",
|
||||
"sha256": "5aeb63b7e05cd86436a5e97e91ca00e27b943fcc2475dee490b21902f5ff23bb",
|
||||
"rawBytes": 1183,
|
||||
"gzipBytes": 797,
|
||||
"gzipBytes": 796,
|
||||
"isEntry": true,
|
||||
"imports": [
|
||||
"houseplan-assets/houseplan-card-DoTfrXZx.js"
|
||||
"houseplan-assets/houseplan-card-tbclbSeu.js"
|
||||
],
|
||||
"dynamicImports": []
|
||||
}
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,4 +1,4 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c3f3b28b3149752a2b63584dbe161b2a247db77770fd5bd84bd87a14f303b3a6";import{b as e,l as o,t,d8 as s,A as a,d9 as i,da as l,db as n,E as r,c}from"./houseplan-card-DoTfrXZx.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
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="86bca8107c5d9e57b05a46242a839b6a888240ff8560cc296275e39dbc668668";import{b as e,l as o,t,d8 as s,A as a,d9 as i,da as l,db as n,E as r,c}from"./houseplan-card-tbclbSeu.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}
|
||||
+1
-1
File diff suppressed because one or more lines are too long
Vendored
+3
-3
File diff suppressed because one or more lines are too long
+28
-28
File diff suppressed because one or more lines are too long
+7
-7
File diff suppressed because one or more lines are too long
Vendored
+1
-1
@@ -1 +1 @@
|
||||
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="c3f3b28b3149752a2b63584dbe161b2a247db77770fd5bd84bd87a14f303b3a6";try{await import("./houseplan-assets/houseplan-card-DoTfrXZx.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__="86bca8107c5d9e57b05a46242a839b6a888240ff8560cc296275e39dbc668668";try{await import("./houseplan-assets/houseplan-card-tbclbSeu.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
|
||||
|
||||
- **Help & feedback** now keeps attachment consent authoritative when preview
|
||||
responses arrive late, and edited retries receive a fresh idempotency key so
|
||||
the updated report reaches support
|
||||
([#418](https://github.com/Matysh/houseplan-card/issues/418)).
|
||||
- Dangerous-action confirmation no longer hangs if the active space disappears
|
||||
or a request arrives while a lazy language is switching; House Plan now
|
||||
refuses safely when no confirmation dialog can be rendered
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
|
||||
## Не выпущено
|
||||
|
||||
- **«Помощь и обратная связь»** теперь учитывает отказ от вложения даже при
|
||||
позднем ответе превью, а изменённая повторная отправка получает новый ключ
|
||||
идемпотентности, чтобы исправленный репорт дошёл до поддержки
|
||||
([#418](https://github.com/Matysh/houseplan-card/issues/418)).
|
||||
- Подтверждение опасного действия больше не зависает, если активное пространство
|
||||
исчезло или запрос пришёл во время переключения лениво загружаемого языка:
|
||||
когда показать диалог невозможно, House Plan безопасно отвечает отказом
|
||||
|
||||
@@ -4433,6 +4433,33 @@ const MUTANT_DEFINITIONS = [
|
||||
replace: ' this._devicePositionHistory.clear();',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'support-stale-preview-response-revives-consent',
|
||||
guard: 'node demo/smoke_support_feedback.mjs',
|
||||
because: 'a late preview response must not restore exact plan geometry after attachment '
|
||||
+ 'consent was revoked or a newer preview generation won (#418)',
|
||||
patches: [{
|
||||
file: 'src/houseplan-editor-runtime.ts',
|
||||
find: " return generation === this._supportPreviewGeneration\n"
|
||||
+ ' && current?.draftId === draftId\n'
|
||||
+ ' && current.attach;',
|
||||
replace: ' return true;',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'support-edited-retry-reuses-old-idempotency-key',
|
||||
guard: 'node demo/smoke_support_feedback.mjs',
|
||||
because: 'a retry with changed outbound message, contact or preview must receive a new '
|
||||
+ 'idempotency key instead of resolving to the first payload at the relay (#418)',
|
||||
patches: [{
|
||||
file: 'src/support-feedback.ts',
|
||||
find: ' idempotencyKey: state.submissionFingerprint\n'
|
||||
+ ' && state.submissionFingerprint !== fingerprint\n'
|
||||
+ " ? randomId('report')\n"
|
||||
+ ' : state.idempotencyKey,',
|
||||
replace: ' idempotencyKey: state.idempotencyKey,',
|
||||
}],
|
||||
},
|
||||
{
|
||||
id: 'support-timeout-claims-success',
|
||||
guard: 'node demo/smoke_support_feedback.mjs',
|
||||
|
||||
@@ -252,6 +252,7 @@ import {
|
||||
supportErrorCode,
|
||||
supportRuntimeFacts,
|
||||
supportSizeKiB,
|
||||
supportSubmissionIdentity,
|
||||
type SupportDialogState,
|
||||
type SupportPreview,
|
||||
} from './support-feedback';
|
||||
@@ -1189,6 +1190,7 @@ export class HouseplanEditorRuntime {
|
||||
spaceId: string; fingerprint: string; violations: JunctionLimitViolation[];
|
||||
}>();
|
||||
private _supportExpiryTimer?: number;
|
||||
private _supportPreviewGeneration = 0;
|
||||
|
||||
public constructor(public readonly host: HouseplanEditorHostPort) {
|
||||
host._editorSecondary = new EditorSecondaryController({
|
||||
@@ -9078,6 +9080,7 @@ public _openSupportDialog = (): void => {
|
||||
if (!this.host._norm || !this.host._canEdit) return;
|
||||
clearTimeout(this._supportExpiryTimer);
|
||||
this._supportExpiryTimer = undefined;
|
||||
this._supportPreviewGeneration += 1;
|
||||
this.host._supportDialog = newSupportDialogState();
|
||||
};
|
||||
|
||||
@@ -9190,10 +9193,18 @@ private _supportFacts(): ReturnType<typeof supportRuntimeFacts> {
|
||||
});
|
||||
}
|
||||
|
||||
private _supportPreviewRequestIsCurrent(draftId: string, generation: number): boolean {
|
||||
const current = this.host._supportDialog;
|
||||
return generation === this._supportPreviewGeneration
|
||||
&& current?.draftId === draftId
|
||||
&& current.attach;
|
||||
}
|
||||
|
||||
private async _buildSupportPreview(draftId: string): Promise<void> {
|
||||
const current = this.host._supportDialog;
|
||||
if (!current || current.draftId !== draftId || !current.attach
|
||||
|| this.host._haIntegrationVersion !== CARD_VERSION) return;
|
||||
const generation = ++this._supportPreviewGeneration;
|
||||
this._supportPatch(draftId, { status: 'building', errorCode: '' });
|
||||
try {
|
||||
const response: unknown = await this.host.hass.callWS({
|
||||
@@ -9234,6 +9245,10 @@ private async _buildSupportPreview(draftId: string): Promise<void> {
|
||||
text,
|
||||
preparedAt: now,
|
||||
};
|
||||
if (!this._supportPreviewRequestIsCurrent(draftId, generation)) {
|
||||
void this._discardSupportPreview(token);
|
||||
return;
|
||||
}
|
||||
if (!this._supportPatch(draftId, {
|
||||
status: 'ready',
|
||||
preview,
|
||||
@@ -9245,6 +9260,7 @@ private async _buildSupportPreview(draftId: string): Promise<void> {
|
||||
}
|
||||
this._scheduleSupportExpiry(draftId, preview);
|
||||
} catch (error: unknown) {
|
||||
if (!this._supportPreviewRequestIsCurrent(draftId, generation)) return;
|
||||
if (!this._supportPatch(draftId, {
|
||||
status: 'error',
|
||||
errorCode: supportErrorCode(error),
|
||||
@@ -9258,6 +9274,7 @@ public async _setSupportAttachment(attach: boolean): Promise<void> {
|
||||
if (!current || current.status === 'sending' || current.status === 'success') return;
|
||||
const token = current.preview?.token || '';
|
||||
if (!attach) {
|
||||
this._supportPreviewGeneration += 1;
|
||||
clearTimeout(this._supportExpiryTimer);
|
||||
this._supportExpiryTimer = undefined;
|
||||
this._supportPatch(current.draftId, {
|
||||
@@ -9317,14 +9334,21 @@ public async _submitSupport(): Promise<void> {
|
||||
return;
|
||||
}
|
||||
if (!supportCanSubmit(current)) return;
|
||||
this._supportPatch(current.draftId, { status: 'sending', errorCode: '' });
|
||||
const submission = supportSubmissionIdentity(current);
|
||||
const sending = this._supportPatch(current.draftId, {
|
||||
status: 'sending',
|
||||
errorCode: '',
|
||||
idempotencyKey: submission.idempotencyKey,
|
||||
submissionFingerprint: submission.fingerprint,
|
||||
});
|
||||
if (!sending) return;
|
||||
try {
|
||||
const response: unknown = await this.host.hass.callWS({
|
||||
type: 'houseplan/support/submit',
|
||||
message: current.message.trim(),
|
||||
contact: current.contact.trim(),
|
||||
...(current.attach && current.preview ? { preview_token: current.preview.token } : {}),
|
||||
idempotency_key: current.idempotencyKey,
|
||||
message: sending.message.trim(),
|
||||
contact: sending.contact.trim(),
|
||||
...(sending.attach && sending.preview ? { preview_token: sending.preview.token } : {}),
|
||||
idempotency_key: sending.idempotencyKey,
|
||||
});
|
||||
const reportId = response && typeof response === 'object' && 'report_id' in response
|
||||
? String((response as { report_id?: unknown }).report_id || '') : '';
|
||||
@@ -9433,7 +9457,7 @@ public _renderSupportDialog(): TemplateResult {
|
||||
${state.status === 'building' ? html`<div class="supportstatus" role="status" aria-live="polite">
|
||||
<ha-icon icon="mdi:progress-clock"></ha-icon>${this.host._t('support.building')}
|
||||
</div>` : nothing}
|
||||
${state.preview ? html`
|
||||
${state.attach && state.preview ? html`
|
||||
<div class="supportpreview">
|
||||
<div class="supportsummary">${this.host._t('support.preview_summary', {
|
||||
version: state.preview.version,
|
||||
|
||||
@@ -26,6 +26,7 @@ export type SupportDialogStatus =
|
||||
export interface SupportDialogState {
|
||||
draftId: string;
|
||||
idempotencyKey: string;
|
||||
submissionFingerprint: string;
|
||||
contact: string;
|
||||
message: string;
|
||||
attach: boolean;
|
||||
@@ -52,10 +53,32 @@ function randomId(prefix: string): string {
|
||||
return `${prefix}-${id}`;
|
||||
}
|
||||
|
||||
export function supportSubmissionFingerprint(state: SupportDialogState): string {
|
||||
return JSON.stringify({
|
||||
message: state.message.trim(),
|
||||
contact: state.contact.trim(),
|
||||
previewToken: state.attach && state.preview ? state.preview.token : '',
|
||||
});
|
||||
}
|
||||
|
||||
export function supportSubmissionIdentity(
|
||||
state: SupportDialogState,
|
||||
): { idempotencyKey: string; fingerprint: string } {
|
||||
const fingerprint = supportSubmissionFingerprint(state);
|
||||
return {
|
||||
idempotencyKey: state.submissionFingerprint
|
||||
&& state.submissionFingerprint !== fingerprint
|
||||
? randomId('report')
|
||||
: state.idempotencyKey,
|
||||
fingerprint,
|
||||
};
|
||||
}
|
||||
|
||||
export function newSupportDialogState(): SupportDialogState {
|
||||
return {
|
||||
draftId: randomId('draft'),
|
||||
idempotencyKey: randomId('report'),
|
||||
submissionFingerprint: '',
|
||||
contact: '',
|
||||
message: '',
|
||||
attach: false,
|
||||
|
||||
@@ -8,6 +8,8 @@ import {
|
||||
supportDraftError,
|
||||
supportErrorCode,
|
||||
supportRuntimeFacts,
|
||||
supportSubmissionFingerprint,
|
||||
supportSubmissionIdentity,
|
||||
} from '../test-build/support-feedback.js';
|
||||
|
||||
test('a fresh dialog never opts into exact plan geometry', () => {
|
||||
@@ -39,6 +41,47 @@ test('attachment submit requires the exact non-expired preview', () => {
|
||||
assert.equal(supportDraftError({ ...base, preview }, now + 1), 'preview_expired');
|
||||
});
|
||||
|
||||
test('submission identity follows the effective trimmed payload', () => {
|
||||
const initial = {
|
||||
...newSupportDialogState(),
|
||||
message: ' first message ',
|
||||
contact: ' user@example.test ',
|
||||
};
|
||||
const first = supportSubmissionIdentity(initial);
|
||||
assert.equal(first.idempotencyKey, initial.idempotencyKey);
|
||||
assert.equal(
|
||||
first.fingerprint,
|
||||
supportSubmissionFingerprint({ ...initial, message: 'first message', contact: 'user@example.test' }),
|
||||
);
|
||||
|
||||
const attempted = { ...initial, submissionFingerprint: first.fingerprint };
|
||||
assert.equal(
|
||||
supportSubmissionIdentity({ ...attempted, message: 'first message ' }).idempotencyKey,
|
||||
initial.idempotencyKey,
|
||||
);
|
||||
assert.notEqual(
|
||||
supportSubmissionIdentity({ ...attempted, message: 'different message' }).idempotencyKey,
|
||||
initial.idempotencyKey,
|
||||
);
|
||||
assert.notEqual(
|
||||
supportSubmissionIdentity({ ...attempted, contact: 'other@example.test' }).idempotencyKey,
|
||||
initial.idempotencyKey,
|
||||
);
|
||||
|
||||
const preview = {
|
||||
token: 'a'.repeat(48), expiresAt: Date.now() + 1_000, size: 2, sha256: 'b'.repeat(64),
|
||||
spaces: 1, format: 'houseplan-support-package', version: 1, text: '{}\n', preparedAt: Date.now(),
|
||||
};
|
||||
assert.notEqual(
|
||||
supportSubmissionIdentity({ ...attempted, attach: true, preview }).idempotencyKey,
|
||||
initial.idempotencyKey,
|
||||
);
|
||||
assert.equal(
|
||||
supportSubmissionFingerprint({ ...attempted, attach: false, preview }),
|
||||
first.fingerprint,
|
||||
);
|
||||
});
|
||||
|
||||
test('runtime facts are bounded enums without a raw user agent', () => {
|
||||
const facts = supportRuntimeFacts({
|
||||
userAgent: 'Mozilla/5.0 Chrome/140.0.0.0 Safari/537.36 private-suffix',
|
||||
|
||||
Reference in New Issue
Block a user