Compare commits

...
Author SHA1 Message Date
claude[bot] 27920a7919 docs: review document for #415
Issue: #415
User-Visible: no
2026-09-02 05:08:47 +00:00
Sergey Matyunin b012280373 docs: refresh reviewed support screenshots
Canonical Linux capture: https://github.com/Matysh/houseplan-card/actions/runs/33592550716
Eight changed frames were reviewed; two byte-identical frames remain as environment witnesses.

Issue: #415
User-Visible: no
2026-09-02 07:57:08 +03:00
claude[bot]andSergey Matyunin c6fac8bf1c docs: review document for #415
Issue: #415
User-Visible: no
2026-09-02 07:53:28 +03:00
Sergey Matyunin d1691f4bc2 fix: align support controls
Issue: #415
User-Visible: yes
2026-09-02 07:53:28 +03:00
36 changed files with 580 additions and 180 deletions
@@ -1,125 +1,125 @@
{
"schema": 1,
"fingerprint": "cfeec183260c075204dd0fdd0333fdf69f1bab8b9e9142483b49b645e0526710",
"fingerprint": "baf59953cfd6eb3543f7da5af21787b20dc76f136b74782ae917f811d2fc1ab5",
"entry": "houseplan-card.js",
"initialViewFiles": [
"houseplan-assets/houseplan-card-DdbeLYki.js",
"houseplan-assets/houseplan-card-BGFqEA3T.js",
"houseplan-card.js"
],
"initialViewGzipBytes": 290375,
"initialViewGzipBytes": 290391,
"lazyFiles": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/de-h-9CiLUA.js",
"houseplan-assets/editor-BcMfn7wA.js",
"houseplan-assets/fr-JMJhplAF.js",
"houseplan-assets/houseplan-editor-runtime-DBsb8Jgp.js",
"houseplan-assets/houseplan-onboarding-runtime-DuBh8LrV.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/de-CNmZS2Bl.js",
"houseplan-assets/editor-CcKD8T48.js",
"houseplan-assets/fr-ChOylnG-.js",
"houseplan-assets/houseplan-editor-runtime-BKOSee7A.js",
"houseplan-assets/houseplan-onboarding-runtime-B8zj38Pl.js"
],
"lazyGzipBytes": 205825,
"lazyGzipBytes": 205820,
"lazyEditorFiles": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/editor-BcMfn7wA.js",
"houseplan-assets/houseplan-editor-runtime-DBsb8Jgp.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/editor-CcKD8T48.js",
"houseplan-assets/houseplan-editor-runtime-BKOSee7A.js"
],
"lazyEditorGzipBytes": 148717,
"lazyEditorGzipBytes": 148720,
"lazyOnboardingFiles": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/houseplan-onboarding-runtime-DuBh8LrV.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/houseplan-onboarding-runtime-B8zj38Pl.js"
],
"lazyOnboardingGzipBytes": 14030,
"lazyOnboardingGzipBytes": 14028,
"lazyLocaleFiles": [
"houseplan-assets/de-h-9CiLUA.js",
"houseplan-assets/fr-JMJhplAF.js"
"houseplan-assets/de-CNmZS2Bl.js",
"houseplan-assets/fr-ChOylnG-.js"
],
"lazyLocaleGzipBytes": 50148,
"lazyLocaleGzipBytes": 50142,
"files": [
{
"path": "houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"sha256": "056fb0975dfa0f753ff8a606d2276add24f02a92517d3536f02be93857970e83",
"path": "houseplan-assets/backdrop-pick-78QbziGu.js",
"sha256": "26a9c96fdb60fb7fe12df6a09b2c27c26b2b90479cf4968bfc1b32a895c4e944",
"rawBytes": 20636,
"gzipBytes": 7070,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/de-h-9CiLUA.js",
"sha256": "de934d5d3553dd90a853777514c7ec6e67b765adbd4b379bdd5e15b80448bc97",
"path": "houseplan-assets/de-CNmZS2Bl.js",
"sha256": "7850782105783e0dcdb910c7071a101e9a02b00c1c2015dbc05baeb3c47e15cc",
"rawBytes": 83981,
"gzipBytes": 25345,
"gzipBytes": 25342,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/editor-BcMfn7wA.js",
"sha256": "367dd4bd9ef49463e12b3d9f405c5aa221d34fac6559f886a98c27946f4b341e",
"path": "houseplan-assets/editor-CcKD8T48.js",
"sha256": "61452fe308e80615a91df46691524b34a71022e6aa9168b3010acf8608899c45",
"rawBytes": 3826,
"gzipBytes": 1581,
"gzipBytes": 1582,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/fr-JMJhplAF.js",
"sha256": "d11639e11eac93a821abd81307203d8ca00ab14d3fade8e4049be725fee60df5",
"path": "houseplan-assets/fr-ChOylnG-.js",
"sha256": "11a94a647483fa90c9b79f9f45206ffc5f9d5008cb0c2227f53654399ad8e574",
"rawBytes": 86212,
"gzipBytes": 24803,
"gzipBytes": 24800,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/houseplan-card-DdbeLYki.js",
"sha256": "85dbbe6644990d350c9658b44514ae5db444203ed537c2d01726f267d2766679",
"rawBytes": 1032271,
"gzipBytes": 289578,
"path": "houseplan-assets/houseplan-card-BGFqEA3T.js",
"sha256": "2f556d1f30b8368e1a866a171031f42968b0c6f00aa40d9f25d650b8bc469fa6",
"rawBytes": 1032340,
"gzipBytes": 289594,
"isEntry": false,
"imports": [],
"dynamicImports": [
"houseplan-assets/de-h-9CiLUA.js",
"houseplan-assets/editor-BcMfn7wA.js",
"houseplan-assets/fr-JMJhplAF.js",
"houseplan-assets/houseplan-editor-runtime-DBsb8Jgp.js",
"houseplan-assets/houseplan-onboarding-runtime-DuBh8LrV.js"
"houseplan-assets/de-CNmZS2Bl.js",
"houseplan-assets/editor-CcKD8T48.js",
"houseplan-assets/fr-ChOylnG-.js",
"houseplan-assets/houseplan-editor-runtime-BKOSee7A.js",
"houseplan-assets/houseplan-onboarding-runtime-B8zj38Pl.js"
]
},
{
"path": "houseplan-assets/houseplan-editor-runtime-DBsb8Jgp.js",
"sha256": "5889a92ae87a014f6e858b94da6f4683c10637384b44263156d23e2e52fea3e3",
"path": "houseplan-assets/houseplan-editor-runtime-BKOSee7A.js",
"sha256": "8361e79183dfc42c6aae966758c29018b4143d7cfae6a86d7bba886f68238dd1",
"rawBytes": 543272,
"gzipBytes": 140066,
"gzipBytes": 140068,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/houseplan-onboarding-runtime-DuBh8LrV.js",
"sha256": "68031aa68413c961ea1dd1c10fd0b3fe40775425dad227ea680ddc22c2e96f09",
"path": "houseplan-assets/houseplan-onboarding-runtime-B8zj38Pl.js",
"sha256": "c8eed0234c0928fcf49cca348ab38640f4662c85d2f3fc9b84a68f28e26ac214",
"rawBytes": 28088,
"gzipBytes": 6960,
"gzipBytes": 6958,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
},
{
"path": "houseplan-card.js",
"sha256": "cacb921be9d92f674ba3fca7bd7bf07427d1a6e2e626b8a36d56aca54ae1d7e9",
"sha256": "588c8aef7a904a7f4522ee1fa04949f3dc29dec8e9c3910234ff76d996a151cf",
"rawBytes": 1183,
"gzipBytes": 797,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
}
File diff suppressed because one or more lines are too long
@@ -1,14 +1,14 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="cfeec183260c075204dd0fdd0333fdf69f1bab8b9e9142483b49b645e0526710";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-DdbeLYki.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__="baf59953cfd6eb3543f7da5af21787b20dc76f136b74782ae917f811d2fc1ab5";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-BGFqEA3T.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
.hass=${this.hass}
.data=${this._formData}
.schema=${e}
.computeLabel=${e=>h[e.name]||e.name}
.computeLabel=${e=>f[e.name]||e.name}
@value-changed=${this._valueChanged}
></ha-form>`;return c`
${d(f.slice(0,3))}
${d(h.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(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);
${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);
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="cfeec183260c075204dd0fdd0333fdf69f1bab8b9e9142483b49b645e0526710";try{await import("./houseplan-assets/houseplan-card-DdbeLYki.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__="baf59953cfd6eb3543f7da5af21787b20dc76f136b74782ae917f811d2fc1ab5";try{await import("./houseplan-assets/houseplan-card-BGFqEA3T.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)}
+11 -1
View File
@@ -125,7 +125,12 @@ const result = await page.evaluate(async ({ version, previewText, previewSha })
const supportCallsBeforeOpen = calls.length;
await open();
const dialog = root().querySelector('#support-dialog');
const touchRect = root().querySelector('.support-button').getBoundingClientRect();
const supportButton = root().querySelector('.support-button');
const settingsButton = supportButton?.previousElementSibling;
const touchRect = supportButton.getBoundingClientRect();
const settingsRect = settingsButton?.getBoundingClientRect();
const message = dialog?.querySelector('#support-message');
const contact = dialog?.querySelector('#support-contact');
const guide = dialog?.querySelector('#support-docs-heading + a');
out.openIsLocal = calls.length === supportCallsBeforeOpen;
out.aboutAndEnglishGuide = !!dialog?.querySelector('.aboutver')
@@ -135,6 +140,11 @@ const result = await page.evaluate(async ({ version, previewText, previewSha })
&& dialog?.querySelector('#support-message')?.value === ''
&& dialog?.querySelector('.supportattach input')?.checked === false;
out.touchTarget = touchRect.width >= 44 && touchRect.height >= 44;
out.headerActionsMatch = !!settingsRect
&& Math.abs(touchRect.width - settingsRect.width) < 0.01
&& Math.abs(touchRect.height - settingsRect.height) < 0.01;
out.messageSurfaceMatchesContact = !!message && !!contact
&& getComputedStyle(message).backgroundColor === getComputedStyle(contact).backgroundColor;
out.noHorizontalOverflow = dialog.scrollWidth <= dialog.clientWidth + 1
&& dialog.querySelector('.supportbody').scrollWidth
<= dialog.querySelector('.supportbody').clientWidth + 1;
+54 -54
View File
@@ -1,125 +1,125 @@
{
"schema": 1,
"fingerprint": "cfeec183260c075204dd0fdd0333fdf69f1bab8b9e9142483b49b645e0526710",
"fingerprint": "baf59953cfd6eb3543f7da5af21787b20dc76f136b74782ae917f811d2fc1ab5",
"entry": "houseplan-card.js",
"initialViewFiles": [
"houseplan-assets/houseplan-card-DdbeLYki.js",
"houseplan-assets/houseplan-card-BGFqEA3T.js",
"houseplan-card.js"
],
"initialViewGzipBytes": 290375,
"initialViewGzipBytes": 290391,
"lazyFiles": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/de-h-9CiLUA.js",
"houseplan-assets/editor-BcMfn7wA.js",
"houseplan-assets/fr-JMJhplAF.js",
"houseplan-assets/houseplan-editor-runtime-DBsb8Jgp.js",
"houseplan-assets/houseplan-onboarding-runtime-DuBh8LrV.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/de-CNmZS2Bl.js",
"houseplan-assets/editor-CcKD8T48.js",
"houseplan-assets/fr-ChOylnG-.js",
"houseplan-assets/houseplan-editor-runtime-BKOSee7A.js",
"houseplan-assets/houseplan-onboarding-runtime-B8zj38Pl.js"
],
"lazyGzipBytes": 205825,
"lazyGzipBytes": 205820,
"lazyEditorFiles": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/editor-BcMfn7wA.js",
"houseplan-assets/houseplan-editor-runtime-DBsb8Jgp.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/editor-CcKD8T48.js",
"houseplan-assets/houseplan-editor-runtime-BKOSee7A.js"
],
"lazyEditorGzipBytes": 148717,
"lazyEditorGzipBytes": 148720,
"lazyOnboardingFiles": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/houseplan-onboarding-runtime-DuBh8LrV.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/houseplan-onboarding-runtime-B8zj38Pl.js"
],
"lazyOnboardingGzipBytes": 14030,
"lazyOnboardingGzipBytes": 14028,
"lazyLocaleFiles": [
"houseplan-assets/de-h-9CiLUA.js",
"houseplan-assets/fr-JMJhplAF.js"
"houseplan-assets/de-CNmZS2Bl.js",
"houseplan-assets/fr-ChOylnG-.js"
],
"lazyLocaleGzipBytes": 50148,
"lazyLocaleGzipBytes": 50142,
"files": [
{
"path": "houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"sha256": "056fb0975dfa0f753ff8a606d2276add24f02a92517d3536f02be93857970e83",
"path": "houseplan-assets/backdrop-pick-78QbziGu.js",
"sha256": "26a9c96fdb60fb7fe12df6a09b2c27c26b2b90479cf4968bfc1b32a895c4e944",
"rawBytes": 20636,
"gzipBytes": 7070,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/de-h-9CiLUA.js",
"sha256": "de934d5d3553dd90a853777514c7ec6e67b765adbd4b379bdd5e15b80448bc97",
"path": "houseplan-assets/de-CNmZS2Bl.js",
"sha256": "7850782105783e0dcdb910c7071a101e9a02b00c1c2015dbc05baeb3c47e15cc",
"rawBytes": 83981,
"gzipBytes": 25345,
"gzipBytes": 25342,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/editor-BcMfn7wA.js",
"sha256": "367dd4bd9ef49463e12b3d9f405c5aa221d34fac6559f886a98c27946f4b341e",
"path": "houseplan-assets/editor-CcKD8T48.js",
"sha256": "61452fe308e80615a91df46691524b34a71022e6aa9168b3010acf8608899c45",
"rawBytes": 3826,
"gzipBytes": 1581,
"gzipBytes": 1582,
"isEntry": false,
"imports": [
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/fr-JMJhplAF.js",
"sha256": "d11639e11eac93a821abd81307203d8ca00ab14d3fade8e4049be725fee60df5",
"path": "houseplan-assets/fr-ChOylnG-.js",
"sha256": "11a94a647483fa90c9b79f9f45206ffc5f9d5008cb0c2227f53654399ad8e574",
"rawBytes": 86212,
"gzipBytes": 24803,
"gzipBytes": 24800,
"isEntry": false,
"imports": [],
"dynamicImports": []
},
{
"path": "houseplan-assets/houseplan-card-DdbeLYki.js",
"sha256": "85dbbe6644990d350c9658b44514ae5db444203ed537c2d01726f267d2766679",
"rawBytes": 1032271,
"gzipBytes": 289578,
"path": "houseplan-assets/houseplan-card-BGFqEA3T.js",
"sha256": "2f556d1f30b8368e1a866a171031f42968b0c6f00aa40d9f25d650b8bc469fa6",
"rawBytes": 1032340,
"gzipBytes": 289594,
"isEntry": false,
"imports": [],
"dynamicImports": [
"houseplan-assets/de-h-9CiLUA.js",
"houseplan-assets/editor-BcMfn7wA.js",
"houseplan-assets/fr-JMJhplAF.js",
"houseplan-assets/houseplan-editor-runtime-DBsb8Jgp.js",
"houseplan-assets/houseplan-onboarding-runtime-DuBh8LrV.js"
"houseplan-assets/de-CNmZS2Bl.js",
"houseplan-assets/editor-CcKD8T48.js",
"houseplan-assets/fr-ChOylnG-.js",
"houseplan-assets/houseplan-editor-runtime-BKOSee7A.js",
"houseplan-assets/houseplan-onboarding-runtime-B8zj38Pl.js"
]
},
{
"path": "houseplan-assets/houseplan-editor-runtime-DBsb8Jgp.js",
"sha256": "5889a92ae87a014f6e858b94da6f4683c10637384b44263156d23e2e52fea3e3",
"path": "houseplan-assets/houseplan-editor-runtime-BKOSee7A.js",
"sha256": "8361e79183dfc42c6aae966758c29018b4143d7cfae6a86d7bba886f68238dd1",
"rawBytes": 543272,
"gzipBytes": 140066,
"gzipBytes": 140068,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
},
{
"path": "houseplan-assets/houseplan-onboarding-runtime-DuBh8LrV.js",
"sha256": "68031aa68413c961ea1dd1c10fd0b3fe40775425dad227ea680ddc22c2e96f09",
"path": "houseplan-assets/houseplan-onboarding-runtime-B8zj38Pl.js",
"sha256": "c8eed0234c0928fcf49cca348ab38640f4662c85d2f3fc9b84a68f28e26ac214",
"rawBytes": 28088,
"gzipBytes": 6960,
"gzipBytes": 6958,
"isEntry": false,
"imports": [
"houseplan-assets/backdrop-pick-BDzJ-1w0.js",
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/backdrop-pick-78QbziGu.js",
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
},
{
"path": "houseplan-card.js",
"sha256": "cacb921be9d92f674ba3fca7bd7bf07427d1a6e2e626b8a36d56aca54ae1d7e9",
"sha256": "588c8aef7a904a7f4522ee1fa04949f3dc29dec8e9c3910234ff76d996a151cf",
"rawBytes": 1183,
"gzipBytes": 797,
"isEntry": true,
"imports": [
"houseplan-assets/houseplan-card-DdbeLYki.js"
"houseplan-assets/houseplan-card-BGFqEA3T.js"
],
"dynamicImports": []
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,14 +1,14 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="cfeec183260c075204dd0fdd0333fdf69f1bab8b9e9142483b49b645e0526710";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-DdbeLYki.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__="baf59953cfd6eb3543f7da5af21787b20dc76f136b74782ae917f811d2fc1ab5";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-BGFqEA3T.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
.hass=${this.hass}
.data=${this._formData}
.schema=${e}
.computeLabel=${e=>h[e.name]||e.name}
.computeLabel=${e=>f[e.name]||e.name}
@value-changed=${this._valueChanged}
></ha-form>`;return c`
${d(f.slice(0,3))}
${d(h.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(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);
${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);
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
+1 -1
View File
@@ -1 +1 @@
globalThis.__HOUSEPLAN_BUILD_FINGERPRINT__="cfeec183260c075204dd0fdd0333fdf69f1bab8b9e9142483b49b645e0526710";try{await import("./houseplan-assets/houseplan-card-DdbeLYki.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__="baf59953cfd6eb3543f7da5af21787b20dc76f136b74782ae917f811d2fc1ab5";try{await import("./houseplan-assets/houseplan-card-BGFqEA3T.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)}
+4
View File
@@ -2,6 +2,10 @@
## Unreleased
- **Help & feedback** now uses the same 44 px header button as General settings,
and its message field uses the ordinary input surface instead of a grey tint
([#415](https://github.com/Matysh/houseplan-card/issues/415)).
## v1.70.0-beta.3 — 2026-09-02
- The new **Help & feedback** dialog keeps version, documentation and project
+5
View File
@@ -8,6 +8,11 @@
## Не выпущено
- Кнопка **«Помощь и обратная связь»** теперь совпадает по размеру 44 px с
кнопкой «Общие настройки», а поле сообщения использует обычный фон поля ввода
вместо серой заливки
([#415](https://github.com/Matysh/houseplan-card/issues/415)).
## v1.70.0-beta.3 — 2026-09-02
- Новый диалог **«Помощь и обратная связь»** объединяет версию, документацию и
Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 KiB

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 KiB

After

Width:  |  Height:  |  Size: 285 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 KiB

After

Width:  |  Height:  |  Size: 272 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 246 KiB

After

Width:  |  Height:  |  Size: 228 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 KiB

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 243 KiB

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 116 KiB

+21 -24
View File
@@ -3,7 +3,7 @@
"fixture": "synthetic-only",
"chromium": "151.0.7922.34",
"oxipng": "oxipng 10.2.0",
"sourceFingerprint": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"sourceFingerprint": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"captureScriptSha256": "135dd9a566653b05cae3010d7861fca6453daef0ecdcdf1ba10059e65f0d4de8",
"command": "npm run build && node demo/docs/capture.mjs",
"scenarios": {
@@ -15,8 +15,8 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"imageSha256": "f4ecb7fd1f107ccda6c8a1e90be1bce0f2690f93e5e42776ca783297f4143135"
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "e0d39cfae61d194e85147ca36499abc5a173efdf00195f2f00a7111866dd54bd"
},
"view-touch": {
"file": "02-view-touch.png",
@@ -26,7 +26,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "946801f6475a40c0e31a70e4b67eaa34c6f70df5329a63915f445e6e4811ca6a"
},
"space-create": {
@@ -37,7 +37,7 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "617b51b3648498787b5039980c9f3eceb75ba56ed63a1a20e616bc05bc304362"
},
"room-contour-close": {
@@ -48,8 +48,8 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"imageSha256": "9a79b7e517741e74701d1172ec3c66a340aaa9049a7f7a7b2fe86f4c3a2eccf0"
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "f81cfc6b9e4a923d36031c514f02927a33e8b8b2c75f007e8aed45dee16e491d"
},
"plan-context-tray": {
"file": "05-plan-context-tray.png",
@@ -59,8 +59,8 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"imageSha256": "8fb569f326627700e08156c1ca35a4042bcb529a955663b54228d04357c881d0"
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "6b8bfaada24ff1fadcda1b6946a5894d90d981e2c7f7096273e23bfa58ac3218"
},
"device-editor": {
"file": "06-device-editor.png",
@@ -70,8 +70,8 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"imageSha256": "720fc3aa2070d1fcf6907091941751c623f30cc6a001ff95e22de9be998136df"
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "a13536d93f5bf70207e7ece0d3f4617d4ba919cb556342de67eaa81961589fb2"
},
"device-display-preview": {
"file": "06-device-display-preview.png",
@@ -81,8 +81,8 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"imageSha256": "b2294c6de0b18ef386b5a2d18422a866b84d095f133d31e56e307664e31e5bc0"
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "d93be8761de4451fa792cc4415789b4624f38638eccc3623502ea61dcf3b3a13"
},
"background-editor": {
"file": "07-background-editor.png",
@@ -92,8 +92,8 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"imageSha256": "8dbc5864124c4bddbe076722a1503e666c40f432cfe7fff86e6d196c428365f3"
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "054170fd9ef45762b602b4d5c9c3b9ea9724858be61af137970c246f485c13bb"
},
"room-card": {
"file": "08-room-card.png",
@@ -103,8 +103,8 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"imageSha256": "d09709ae1479cfaa1902068cb2a6015dfee3b58f1bbd349bafaa2c0592812463"
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "2ae4a58853d98e10d12456b2078ec2f6a0b597722c8310d7b016abd2bc42561e"
},
"device-info": {
"file": "09-device-info.png",
@@ -114,15 +114,13 @@
},
"theme": "dark",
"language": "en",
"sourceSha256": "c3e3e7dba1910e09c702472e6ea09d7ef13b91e082c09d2f9474437c776fb26e",
"imageSha256": "c0b20a31c2987c8737e7b746c7d358e6c97231ea7e06d73050a2d3aebb216558"
"sourceSha256": "51672b157f9dfe4f36747b0c8963b079295b67ec3c93e33f3c18287aca59fa90",
"imageSha256": "cb37f7eefd936f98ef44969b21dfe8e40ee27d1f558abe8d53c0223f6488b8a6"
}
},
"acceptance": {
"declared": [
"view-desktop",
"view-touch",
"space-create",
"room-contour-close",
"plan-context-tray",
"device-editor",
@@ -131,8 +129,7 @@
"room-card",
"device-info"
],
"witnesses": 0,
"floor": 1,
"witnessesSkippedBecause": "сменились флаги растеризации и обрезка стала целой (#410)"
"witnesses": 2,
"floor": 1
}
}
+178
View File
@@ -0,0 +1,178 @@
# CODE-REVIEW-415-r1
Issue: #415 — «Полиш диалога помощи: размер кнопки и белый фон сообщения»
Ветка: `issue/415-support-visual-polish`
SHA ревью: `2fc8c1203782026bb45647ad54ef11857f7eb2c3`
Трек: `trivial` (AC в теле issue, без файла в `docs/specs/`) — этап ревью: **code**.
Заход: r1 (первый цикл, предыдущих раундов и вердиктов нет — разбор полный).
## Скоуп
Issue фиксирует два визуальных расхождения после #43:
- **AC1 (smoke):** кнопки «Общие настройки» и «Помощь и обратная связь» в одной
шапке должны иметь одинаковые фактические ширину и высоту; отдельный размер
для кнопки помощи не задаётся.
- **AC2 (smoke + golden перед бетой):** поле «Сообщение» должно использовать ту
же поверхность ввода, что поле контакта (белую в светлой теме, штатную
тёмную — в тёмной); read-only preview (`.supportraw`) не меняется.
Затронутые файлы по диффу: `src/houseplan-card.ts`, `src/styles/plan.styles.ts`,
`src/styles/dialogs.styles.ts`, `demo/smoke_support_feedback.mjs`,
`test/support-feedback.test.mjs`, оба changelog, сгенерированные бандлы (класс D).
Без i18n, без миграции, без geometry — совпадает с заявленным в issue «Затрагиваемое».
## Как проверялось
| Гейт | Команда | Результат |
|---|---|---|
| Типы | `npx tsc --noEmit` | зелёный, без вывода |
| Юнит-тесты | `npm test` | 1724 passed / 0 failed / 1 skipped (совпадает с хендоффом автора) |
| Сборка + сверка бандла | `npm run build && cmp dist/houseplan-card.js custom_components/houseplan/frontend/houseplan-card.js` | идентичны |
| Новый `any` | `node scripts/no-new-any.mjs --base origin/dev --head HEAD` | 7 добавленных строк в 3 файлах, новых `any` нет |
| Выбор смоков | `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | см. раздел ниже |
| Целевой смок (AC1+AC2) | `node demo/smoke_support_feedback.mjs` | **OK**, включая новые поля `headerActionsMatch`, `messageSurfaceMatchesContact` |
| Смок-спецпроверка на падение | тот же смок на `src/*` из родительского коммита `afe5e989` | `headerActionsMatch: false`, `messageSurfaceMatchesContact: false` — тест умеет падать |
| Документационный гейт | `node scripts/check-docs.mjs` | **ERROR: screenshot source fingerprint is stale** |
| То же на `origin/dev` (`afe5e989`) | `node scripts/check-docs.mjs` (с исходниками родителя) | зелёный — подтверждает, что именно этот диф делает отпечаток устаревшим |
Рабочее дерево после всех экспериментов с временным `git checkout` родительских
версий файлов возвращено в исходное состояние; `git status --porcelain` пуст,
`git rev-parse HEAD` = `2fc8c120...`, сгенерированные файлы побайтово совпадают
с `HEAD` (`cmp` зелёный).
### Выбор браузерных смоков (`scripts/smoke-select.mjs`)
```
Изменено файлов src/**: 3 · символов проекта на изменённых строках: 2
Матрица: 213 смоков · порог «широкого» символа: больше 42 смоков
Прямое совпадение (9):
demo/smoke_backup_transfer.mjs ← _openSettingsDialog
demo/smoke_bg_color.mjs ← _openSettingsDialog
demo/smoke_color_picker_consumers.mjs ← _openSettingsDialog
demo/smoke_dialog_zombie.mjs ← _openSettingsDialog
demo/smoke_esc_dialogs.mjs ← _openSettingsDialog
demo/smoke_general_settings.mjs ← _openSettingsDialog
demo/smoke_ha_controls.mjs ← _openSettingsDialog
demo/smoke_help_affordance.mjs ← _openSettingsDialog
demo/smoke_sun.mjs ← _openSettingsDialog
```
Инструмент не назвал `demo/smoke_support_feedback.mjs` (совпадение идёт по
имени JS-символа на изменённой строке, а не по предметной области; сам смок
селектор `.support-button`, а не `_openSupportDialog`, не матчит построчно) —
он взят отдельно, так как прямо назван в AC1/AC2.
Решение по 9 найденным смокам: причина совпадения — обе кнопки шапки лежат на
строке, где стоит вызов `_openSettingsDialog`/`_openSupportDialog`; сама функция
не менялась, менялся только список CSS-классов элемента. Прогнал два самых
предметно близких — `smoke_general_settings.mjs` (диалог настроек целиком) и
`smoke_help_affordance.mjs` (соседняя механика помощи/подсказок) — оба **OK**
без регрессий в открытии диалогов и фокусе. Остальные 7 (`backup_transfer`,
`bg_color`, `color_picker_consumers`, `dialog_zombie`, `esc_dialogs`,
`ha_controls`, `sun`) не прогонял: они используют `_openSettingsDialog` только
как способ добраться до необязанной с этим issue функциональности, а
изменение — чисто визуальное (класс `header-action`, без изменения обработчика
клика или разметки диалогов). Полный прогон всех 213 смоков — предрелизный
гейт, не гейт ревью (§8), и здесь ему делать нечего: диф не «задевает всё».
### Что не проверял и почему
- **`npm run golden:verify`** — не прогонял. AC2 сам относит golden-проверку к
«перед бетой», а не к код-ревью; в `demo/golden/` нет сценариев, ссылающихся
на `.support-button`, `.header-action` или `.supportmessage` — совпадает с
этим разделением.
- **`node scripts/model-invariants.mjs`** — не прогонял. Диф не касается
геометрии, рёбер, `layout`, `marker.space`, `open_spans`.
- **`python -m pytest tests_backend`** — не прогонял. `custom_components/**/*.py`
не тронут.
- **Performance-профили** — не названы в AC, не прогонял.
- Остальные 7 из 9 «прямое совпадение» смоков — см. решение выше.
## Находки
### High — check-docs: отпечаток скриншотов документации устарел
`node scripts/check-docs.mjs` падает на этом SHA:
`ERROR screenshot source fingerprint is stale; run npm run build && node demo/docs/capture.mjs`.
Этот гейт — часть `validate.yml` (`node scripts/check-docs.mjs --external`),
то есть часть CI Validate, а не только локальная рекомендация. Проверено, что
регрессия внесена именно этим коммитом: на исходниках родителя
(`afe5e989`, = `origin/dev`) тот же скрипт зелёный
(«Documentation checks passed»); после возврата `src/houseplan-card.ts`,
`src/styles/plan.styles.ts`, `src/styles/dialogs.styles.ts` к текущему SHA
скрипт снова красный. Причина устройства гейта задокументирована в PROCESS.md
§8: отпечаток считается по всему `src/**`, поэтому любая правка фронтенда
делает его устаревшим безусловно — «выбирать тут нечего». Ровно этот пропуск
уже дважды стоил продукту красного `docs`-джоба на `dev` (#230, #234, #237);
хендофф автора («Передача на код-ревью») не упоминает пересъёмку скриншотов
вообще.
**Воспроизведение:**
```
$ node scripts/check-docs.mjs
ERROR screenshot source fingerprint is stale; run npm run build && node demo/docs/capture.mjs
```
**Почему High:** гейт входит в обязательную часть CI (`validate.yml`) и
детерминированно красный на этом SHA; слияние в `dev` в этом состоянии
повторяет уже случавшийся инцидент (`dev` с красным `docs`-джобом до следующей
задачи). Это не вопрос вкуса и не техническое несогласие — факт, проверенный
запуском.
**Что нужно для закрытия:** прогнать джобу `Docs screenshots`
(`workflow_dispatch`), принять артефакт локально
`npm run docs:accept -- --reviewed --from=<распакованный артефакт>` и
закоммитить эталоны вместе с задачей (класс D, трейлер `Baseline-Reviewed`).
Это не в моих полномочиях как ревьюера (я не запускаю релизные workflow и не
пишу в репозиторий) и не то, что можно решить локальной правкой кода — гейт
обслуживается человеком/автором по регламенту §8.
## Что проверено и корректно
- **AC1 (кнопки одного размера).** `.support-button` больше не несёт стилей
размера — правило переименовано в `.header-action`
(`src/styles/plan.styles.ts:188`, было `.support-button {min-width:44px...}`)
и навешено на **обе** кнопки шапки (`src/houseplan-card.ts:11496,11499`);
класс `support-button` остался только как селектор-хук для JS/смоков, без
собственных правил стиля (проверено чтением — единственное вхождение строки
`support-button` в `src/**` осталось в шаблоне, ни одного в `*.styles.ts`).
Доказано автотестом: `out.headerActionsMatch` в
`demo/smoke_support_feedback.mjs` сравнивает `getBoundingClientRect()` обеих
кнопок с допуском 0.01px и **умеет падать** — воспроизведено на исходниках
родительского коммита (оба новых поля дают `false`).
- **AC2 (единая поверхность поля).** `.supportmessage` получил явный
`background: var(--hp-bg)` (`src/styles/dialogs.styles.ts:1189-1192`), что
побайтово тот же токен, что использует поле контакта `.namein`
(`src/styles/dialogs.styles.ts:353-355`, тоже `var(--hp-bg)`) — источник
значения один (переменная темы), а не два литерала, вычисляющих одно и то же
число/цвет. `.supportraw` (read-only preview) не тронут: делит с
`.supportmessage` только общий базовый блок правил (border/padding/шрифт), а
собственный фон (`color-mix(...)`) остаётся прежним — соответствует «preview
не меняется». Доказано автотестом `out.messageSurfaceMatchesContact`
(сравнение `getComputedStyle(...).backgroundColor`), тоже проверено на
падение тем же способом.
- **Трейлеры и changelog.** Коммит `2fc8c120` несёт `Issue: #415` и
`User-Visible: yes`; оба changelog (`docs/CHANGELOG.md`,
`docs/CHANGELOG.ru.md`) правлены в том же коммите, формулировки совпадают с
терминологией `docs/USER-GUIDE.ru.md` («Общие настройки», «Помощь и
обратная связь» — см. `docs/USER-GUIDE.ru.md:58,1920`).
- **Тестовый контракт остался честным.** `test/support-feedback.test.mjs`
проверяет ровно две вещи по коду (не только по смоку): что в шапке ровно два
вхождения `header-action` и что `.header-action`/`.supportmessage` содержат
нужные правила — статический дубль-контроль поверх браузерного смока.
- **Никакого расширения скоупа.** Диф ограничен двумя классами CSS и одной
строкой фона; ни новых сценариев, ни миграции, ни i18n, ни touch/perf.
- **Одно число — один источник (44px, фон).** Оба случая сведены к общему
правилу (`.header-action`, `var(--hp-bg)`), а не к двум местам, вычисляющим
одно значение по отдельности — ровно то, о чём предупреждает §8.
## Вывод
Единственная находка — High, блокирующая: `check-docs` детерминированно красный
на этом SHA и является частью CI Validate. AC1 и AC2 при этом выполнены и
доказаны автотестом, который умеет падать. Возврат автору для прогона джобы
скриншотов и коммита эталонов; повторный цикл — по дельте (§2.10), с разделами
«Закрытие раунда r1» и «Унаследовано из r1».
+194
View File
@@ -0,0 +1,194 @@
# CODE-REVIEW-415-r2
Issue: #415 — «Полиш диалога помощи: размер кнопки и белый фон сообщения»
Ветка: `issue/415-support-visual-polish`
SHA ревью: `b0122803737d47950f8c2295b479afa53b8369e0`
Трек: `trivial` (AC в теле issue, без файла в `docs/specs/`) — этап ревью: **code**.
Заход: r2 · блокирующих циклов израсходовано 1 из 2 (зелёный вердикт этого
захода цикл не образует, #227).
## Почему разбор снова полный, а не только по дельте
Между r1 и r2 ветка была **перебазирована на ушедший вперёд `dev`**: r1 стоял на
`afe5e989` (тогдашний `origin/dev`), сейчас `origin/dev` = `206732e9` («ci:
refuse a review round that cites an unreachable SHA», issue #413, чужая
задача — попала в базу только ребейзом). Старый SHA r1
(`2fc8c1203782026bb45647ad54ef11857f7eb2c3`) в дереве больше не существует
(`git cat-file -t` — «could not get object info»): команда `git diff <тот
SHA>..HEAD` из §2.10 не выполнима буквально. Это ровно случай §7.2 «ребейз на
ушедший вперёд `dev` — после ребейза это другой код», поэтому материал этого
раунда — `git diff origin/dev...HEAD` целиком, а не узкая дельта поверх
осиротевшего SHA.
Продуктовый диф при этом **побайтово не менялся** — сверено построчно с телом
CODE-REVIEW-415-r1 (см. ниже раздел «Закрытие раунда r1»): те же три строки в
`src/houseplan-card.ts`, `src/styles/plan.styles.ts`,
`src/styles/dialogs.styles.ts`. Новый код в диапазоне — только пересъёмка
скриншотов и сам документ r1.
## Скоуп
Issue фиксирует два визуальных расхождения после #43:
- **AC1 (smoke):** кнопки «Общие настройки» и «Помощь и обратная связь» в одной
шапке должны иметь одинаковые фактические ширину и высоту; отдельный размер
для кнопки помощи не задаётся.
- **AC2 (smoke + golden перед бетой):** поле «Сообщение» должно использовать ту
же поверхность ввода, что поле контакта (белую в светлой теме, штатную
тёмную — в тёмной); read-only preview (`.supportraw`) не меняется.
Диапазон `origin/dev...HEAD` (3 коммита):
`d1691f4b` fix: align support controls (класс A+B+C, `Issue: #415`,
`User-Visible: yes`) → `c6fac8bf` docs: review document for #415 (класс C,
`User-Visible: no`) → `b0122803` docs: refresh reviewed support screenshots
(класс C — `docs/images/**`, не класс D; `User-Visible: no`).
Затронуто по коду: `src/houseplan-card.ts`, `src/styles/plan.styles.ts`,
`src/styles/dialogs.styles.ts`, `demo/smoke_support_feedback.mjs`,
`test/support-feedback.test.mjs`, оба changelog, бандлы (класс D),
`docs/images/*.png` + `docs/images/screenshots.json` (класс C, пересъёмка).
Без i18n, без миграции, без geometry — совпадает с заявленным в issue
«Затрагиваемое».
## Как проверялось
| Гейт | Команда | Результат |
|---|---|---|
| Типы | `npx tsc --noEmit` | зелёный, без вывода |
| Юнит-тесты | `npm test` | 1729 passed / 0 failed / 1 skipped (совпадает с хендоффом автора) |
| Сборка | `npm run build` | зелёный |
| Сверка бандла (3 копии) | `npm run bundle:sync` → `cmp dist/houseplan-card.js custom_components/.../houseplan-card.js`, `cmp dist/houseplan-assets.json custom_components/.../houseplan-assets.json`, `git status --porcelain` | все три идентичны, рабочее дерево чисто |
| Документационный гейт | `node scripts/check-docs.mjs` | **зелёный** («Documentation checks passed (7 files, 10 external links)») — была High-находка r1, закрыта |
| Новый `any` | `node scripts/no-new-any.mjs --base origin/dev --head HEAD` | 7 добавленных строк в 3 файлах, новых `any` нет |
| Оффлайн-гейт процесса | `node scripts/process-gate.mjs` | «гейт пройден, предупреждений 1» — WARN п.3 (нет `docs/specs/415-*.md`) ожидаемо для трека `trivial` |
| Выбор смоков | `node scripts/smoke-select.mjs --base origin/dev --head HEAD` | см. раздел ниже — идентичен выбору r1 (продуктовый диф не менялся) |
| Целевой смок (AC1+AC2) | `node demo/smoke_support_feedback.mjs` | **OK**, `headerActionsMatch: true`, `messageSurfaceMatchesContact: true` |
| Смок умеет падать | тот же смок на `src/houseplan-card.ts` + оба `*.styles.ts` из `afe5e989` (временный `git checkout`, независимо от r1) | `headerActionsMatch: false`, `messageSurfaceMatchesContact: false` — воспроизведено лично, дерево возвращено (`git status --porcelain` пуст, `cmp` бандла зелёный) |
| Точечные смежные смоки | `node demo/smoke_general_settings.mjs`, `node demo/smoke_help_affordance.mjs` | оба **OK** |
| CI-прогон пересъёмки | `gh run view 33592550716` | `conclusion: success`, workflow «Скриншоты документации», `headSha: c6fac8bf` — ссылка в коммите `b0122803` подтверждена, не выдумана |
| Провенанс пересъёмки | `git diff origin/dev...HEAD -- docs/images/screenshots.json` | 10 сценариев, у всех 10 обновился `sourceSha256` (глобальный отпечаток), у 8 обновился `imageSha256` — ровно совпадает с текстом коммита «Eight changed frames were reviewed; two byte-identical frames remain as environment witnesses» |
### Выбор браузерных смоков (`scripts/smoke-select.mjs`)
Вывод идентичен r1 (продуктовый диф не менялся):
```
Изменено файлов src/**: 3 · символов проекта на изменённых строках: 2
Матрица: 213 смоков · порог «широкого» символа: больше 42 смоков
Прямое совпадение (9): smoke_backup_transfer, smoke_bg_color,
smoke_color_picker_consumers, smoke_dialog_zombie, smoke_esc_dialogs,
smoke_general_settings, smoke_ha_controls, smoke_help_affordance, smoke_sun
← _openSettingsDialog (совпадение по имени JS-символа на изменённой строке,
сама функция не менялась — менялся только список CSS-классов)
```
Решение по 9 найденным — то же, что в r1, и оно не устарело: причина
совпадения (общая строка вызова `_openSettingsDialog`/`_openSupportDialog`, не
сама функция) не изменилась, диф не изменился. Прогнал повторно два самых
предметно близких — `smoke_general_settings.mjs`, `smoke_help_affordance.mjs` —
оба **OK**. Остальные 7 не прогонял по той же причине, что и в r1: чисто
визуальная правка класса, не затрагивающая обработчик клика или разметку
диалогов. Полный прогон всех 213 смоков — предрелизный гейт (§8), не гейт
ревью.
### Что не проверял и почему
- **`npm run golden:verify`** — не прогонял. В `demo/golden/` нет сценариев,
ссылающихся на `.support-button`, `.header-action` или `.supportmessage`
(проверено `grep -rl` по `demo/golden/`) — совпадает с тем, что AC2 сам
относит golden-проверку к «перед бетой», не к код-ревью.
- **`node scripts/model-invariants.mjs`** — не прогонял. Диф не касается
геометрии, рёбер, `layout`, `marker.space`, `open_spans`.
- **`python -m pytest tests_backend`** — не прогонял. `custom_components/**/*.py`
не тронут.
- **Performance-профили** — не названы в AC, не прогонял.
- Остальные 7 из 9 «прямое совпадение» смоков — решение см. выше, не изменилось
с r1.
- Полный прогон 213 смоков — предрелизный гейт, здесь не нужен: диф не «задевает
всё».
## Закрытие раунда r1
| Находка r1 | Чем закрыта | Где это видно |
|---|---|---|
| **High** — `node scripts/check-docs.mjs` красный («screenshot source fingerprint is stale»): диф трогает `src/**`, отпечаток документации считается по всему `src/**` безусловно (§8) | Джоба `Docs screenshots` (`workflow_dispatch`) прогнана, артефакт принят `npm run docs:accept -- --reviewed --from=<артефакт>` с явным `--expect-change` на 8 сценариях, эталоны закоммичены в `b0122803` | `node scripts/check-docs.mjs` → «Documentation checks passed (7 files, 10 external links)» — перепроверено лично на SHA `b0122803`, не только со слов автора; CI-прогон `33592550716` подтверждён `gh run view` как реально существующий `success` |
Других находок в r1 не было — таблица из одной строки полна.
## Унаследовано из r1
Ниже — то, что подтверждено уже в r1 (`docs/reviews/CODE-REVIEW-415-r1.md`, SHA
`2fc8c1203782026bb45647ad54ef11857f7eb2c3`) и **дополнительно перепроверено
лично в этом раунде** тем же способом (документ ревью недостижим по SHA, но
процитированные в нём строки кода сверены построчно с текущим диффом — они не
изменились):
- **AC1.** `.support-button` не несёт стилей размера — правило переименовано в
`.header-action` (`src/styles/plan.styles.ts:188`) и навешено на обе кнопки
шапки (`src/houseplan-card.ts:11496,11499`); `support-button` остался только
как селектор-хук, ноль правил стиля на нём (перепроверено `grep -rn
"support-button" src/` — одно вхождение, в шаблоне). Автотест
`headerActionsMatch` умеет падать — перепроверено лично на исходниках
`afe5e989`, независимо от r1.
- **AC2.** `.supportmessage` получил `background: var(--hp-bg)`
(`src/styles/dialogs.styles.ts`), тот же токен, что `.namein`
(`src/styles/dialogs.styles.ts:355`, тоже `var(--hp-bg)`) — перепроверено
`grep -n ".namein" -A5`. `.supportraw` не тронут — не входит в диф. Автотест
`messageSurfaceMatchesContact` умеет падать — перепроверено тем же способом.
- **Трейлеры и changelog коммита `d1691f4b`** — `Issue: #415`,
`User-Visible: yes`, оба changelog правлены в том же коммите, терминология
совпадает с `docs/USER-GUIDE.ru.md:58,1920` («Общие настройки», «Помощь и
обратная связь») — перепроверено повторным `grep` по гайду.
- **Тестовый контракт `test/support-feedback.test.mjs`** — статический
дубль-контроль поверх браузерного смока (ровно два вхождения
`header-action` в шапке, правило `.header-action` содержит `min-width:44px`,
`.supportmessage` содержит `background: var(--hp-bg)`) — диф файла
перечитан целиком в этом раунде, не только унаследован.
Не перепроверялось заново, унаследовано без замечаний (диф этих утверждений не
касается): продуктовое рассуждение r1 о том, что задача не расширяет скоуп
(«ни новых сценариев, ни миграции, ни i18n, ни touch/perf») — дельта раунда
(рёбейз + пересъёмка скриншотов + документ) этого вывода не задевает.
## Находки
Новых находок нет. Находка r1 (High, check-docs) закрыта и перепроверена лично
(см. выше), новых High/Medium/Low в дельте этого раунда (рёбейз на `206732e9`,
пересъёмка 8 кадров, документ ревью r1) не обнаружено — рёбейз принёс только
чужой, не пересекающийся с этим диффом коммит #413 (CI-инструмент, не
продуктовый код), конфликтов слияния нет (`git status --porcelain` пуст на
каждом шаге проверки).
## Что проверено и корректно
- **AC1 и AC2** — доказаны автотестом, который умеет падать; перепроверено
лично в этом раунде независимо от r1 (см. «Унаследовано из r1»).
- **check-docs** — зелёный на точном SHA `b0122803`, ссылка на реальный
успешный CI-прогон пересъёмки подтверждена через `gh run view`, а не принята
на слово.
- **Провенанс пересъёмки** — 8 изменившихся кадров и 2 кадра-свидетеля в
`screenshots.json` совпадают с формулировкой коммита `b0122803` число в
число.
- **Рёбейз не сломал ничего**: `npm test` (1729/1730), `tsc`, `build`+`cmp`
трёх копий бандла, `process-gate.mjs`, целевой и точечные смоки — все
зелёные на актуальном `origin/dev` (`206732e9`), а не на устаревшей базе.
- **Трейлеры класса C.** `b0122803` трогает только `docs/images/**`
(класс C по таблице §1, не класс D — `dist/**`,
`custom_components/houseplan/frontend/**`, `demo/golden/baselines/**`), и
`scripts/validate-commit-provenance.mjs` требует `Release`/`Baseline-Reviewed`
только для `demo/golden/baselines/*.png|.json` — эта пара трейлеров сюда не
относится; вместо неё коммит несёт содержательную строку «Canonical Linux
capture: <ссылка>» в стиле вывода `scripts/docs-accept.mjs`. Формальных
требований гейта это не нарушает.
- **Никакого расширения скоупа.** Диф раунда — рёбейз, документ ревью,
пересъёмка скриншотов; продуктовый код не менялся ни строкой.
## Вывод
Единственная находка r1 (High, `check-docs`) закрыта и лично перепроверена, а
не принята со слов автора: гейт зелёный, CI-прогон пересъёмки существует и
успешен, провенанс `screenshots.json` совпадает с текстом коммита. Рёбейз на
ушедший вперёд `dev` потребовал полного разбора (§7.2), а не узкой дельты —
проведён полностью: оба AC передоказаны автотестом, который умеет падать,
независимо от r1. Новых находок нет. Вердикт — зелёный.
+2 -2
View File
@@ -11493,10 +11493,10 @@ export class HouseplanCard extends LitElement {
<button class="btn zb" @click=${() => this._stepZoom(1)} title=${this._t('title.zoom_in')}><ha-icon icon="mdi:plus"></ha-icon></button>
</div>
${this._norm && this._canEdit
? html`<button class="btn" @click=${this._openSettingsDialog} title=${this._t('title.general_settings')}>
? html`<button class="btn header-action" @click=${this._openSettingsDialog} title=${this._t('title.general_settings')}>
<ha-icon icon="mdi:cog-outline"></ha-icon>
</button>
<button class="btn support-button" @click=${this._openSupportDialog}
<button class="btn header-action support-button" @click=${this._openSupportDialog}
title=${this._t('support.title')} aria-label=${this._t('support.title')}>
<ha-icon icon="mdi:help-circle-outline"></ha-icon>
</button>`
+4 -1
View File
@@ -1186,7 +1186,10 @@ export const dialogsStyles = css`
background: color-mix(in srgb, var(--card-background-color, var(--hp-bg)) 92%, var(--hp-txt));
font: inherit;
}
.supportmessage { min-height: 120px; }
.supportmessage {
min-height: 120px;
background: var(--hp-bg);
}
.supportraw {
min-height: 220px;
margin-top: var(--sp-2);
+1 -1
View File
@@ -185,7 +185,7 @@ export const planStyles = css`
justify-content: center;
padding: var(--sp-3);
}
.support-button {
.header-action {
min-width: 44px;
min-height: 44px;
justify-content: center;
+4 -1
View File
@@ -63,13 +63,16 @@ test('Help is lazy, ordered after settings, and owns the single About/Guide surf
const card = readFileSync(new URL('../src/houseplan-card.ts', import.meta.url), 'utf8');
const runtime = readFileSync(new URL('../src/houseplan-editor-runtime.ts', import.meta.url), 'utf8');
const styles = readFileSync(new URL('../src/styles/plan.styles.ts', import.meta.url), 'utf8');
const dialogStyles = readFileSync(new URL('../src/styles/dialogs.styles.ts', import.meta.url), 'utf8');
const header = card.slice(card.indexOf('<div class="zoomctl">'), card.indexOf('</div>\n ${this._canEdit'));
assert.ok(header.indexOf('_openSettingsDialog') < header.indexOf('_openSupportDialog'));
assert.match(card, /if \(!this\._editorRuntime\)[\s\S]*?_ensureEditorRuntime\(\)[\s\S]*?_openSupportDialog/);
assert.equal((runtime.match(/_t\('gs\.about_version'/g) || []).length, 1);
assert.match(runtime, /docs\/USER-GUIDE\.ru\.md/);
assert.match(runtime, /docs\/USER-GUIDE\.md/);
assert.match(styles, /\.support-button\s*\{[\s\S]*?min-width:\s*44px;[\s\S]*?min-height:\s*44px;/);
assert.equal((header.match(/header-action/g) || []).length, 2);
assert.match(styles, /\.header-action\s*\{[\s\S]*?min-width:\s*44px;[\s\S]*?min-height:\s*44px;/);
assert.match(dialogStyles, /\.supportmessage\s*\{[\s\S]*?background:\s*var\(--hp-bg\);/);
});
test('the consent copy names exact geometry, project relay, retention and network address', () => {