mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-29 03:09:36 +00:00
92 lines
4.3 KiB
JavaScript
92 lines
4.3 KiB
JavaScript
// #377: the Background editor's default style persists into
|
||
// settings.decor_default_style — one debounced write per palette drag (AC4),
|
||
// and a card born with the key draws new objects with the saved style (AC5).
|
||
import { launch, checkAll, finish } from './serve.mjs';
|
||
const { page, browser } = await launch();
|
||
const res = await page.evaluate(async () => {
|
||
const out = {};
|
||
const c = window.__card;
|
||
const sr = () => c.shadowRoot || c.renderRoot;
|
||
const settleMode = async () => {
|
||
const started = performance.now();
|
||
do { await new Promise((resolve) => requestAnimationFrame(resolve)); }
|
||
while (c._modeTransitionBusy && performance.now() - started < 1500);
|
||
await c.updateComplete;
|
||
};
|
||
const base = c.hass.callWS;
|
||
const writes = [];
|
||
let rev = 40;
|
||
c.hass = { ...c.hass, callWS: async (m) => {
|
||
if (m.type === 'houseplan/config/set') {
|
||
writes.push(JSON.parse(JSON.stringify(m.config.settings?.decor_default_style ?? null)));
|
||
rev += 1;
|
||
return { ok: true, rev };
|
||
}
|
||
return base(m);
|
||
} };
|
||
c._cfgRev = rev;
|
||
|
||
// войти в Background-редактор — там живёт рантайм с _updateDecorStyle
|
||
[...sr().querySelectorAll('.modetab')][2].click(); await settleMode();
|
||
out.decorMode = c._mode === 'decor';
|
||
const runtime = c._editorRuntime;
|
||
out.hasRuntime = !!runtime;
|
||
|
||
// AC4: серия быстрых изменений (драг по палитре) = одна запись после дебаунса
|
||
runtime._updateDecorStyle({ ...c._decorStyle, color: '#101010' });
|
||
runtime._updateDecorStyle({ ...c._decorStyle, color: '#404040' });
|
||
runtime._updateDecorStyle({ ...c._decorStyle, color: '#8b0000' });
|
||
out.instantStyle = c._decorStyle.color === '#8b0000';
|
||
await new Promise((r) => setTimeout(r, 400));
|
||
out.noEagerWrite = writes.length === 0; // дебаунс ещё держит
|
||
// 750 мс > внутренний дебаунс _saveConfig (500 мс): если бы персист ушёл
|
||
// сразу (без своего дебаунса в 1 с), запись уже долетела бы до callWS
|
||
await new Promise((r) => setTimeout(r, 350));
|
||
out.stillNoWriteBeforeDebounce = writes.length === 0;
|
||
await new Promise((r) => setTimeout(r, 550));
|
||
c._saveConfigDebounced?.flush?.();
|
||
await new Promise((r) => setTimeout(r, 200));
|
||
out.oneWrite = writes.length === 1;
|
||
out.writeCarriesKey = !!writes[0] && writes[0].color === '#8b0000'
|
||
&& writes[0].width_cm === 3.6 && writes[0].fill === false;
|
||
|
||
// возврат в дефолт = запись БЕЗ ключа
|
||
runtime._updateDecorStyle({
|
||
color: '#607d8b', opacity: 1, widthCm: 3.6,
|
||
fill: false, fillColor: '#607d8b', fillOpacity: 0.25,
|
||
});
|
||
await new Promise((r) => setTimeout(r, 1100));
|
||
c._saveConfigDebounced?.flush?.();
|
||
await new Promise((r) => setTimeout(r, 200));
|
||
out.defaultRemovesKey = writes.length === 2 && writes[1] === null;
|
||
|
||
// AC5: карта, рождённая с ключом, сеет _decorStyle из него.
|
||
// Чистый reload: кэш мгновенного рендера убираем, чтобы посев шёл из
|
||
// серверного конфига (после настоящей записи кэш нёс бы тот же ключ).
|
||
localStorage.removeItem('houseplan_card_cfg_v1');
|
||
const fresh = document.createElement('houseplan-card');
|
||
fresh.setConfig({ type: 'custom:houseplan-card' });
|
||
fresh.hass = { ...c.hass, callWS: async (m) => {
|
||
if (m.type === 'houseplan/config/get') {
|
||
const r = await base(m);
|
||
const config = JSON.parse(JSON.stringify(r.config));
|
||
config.settings = { ...(config.settings || {}),
|
||
decor_default_style: { color: '#8b0000', width_cm: 5 } };
|
||
return { ...r, config, rev };
|
||
}
|
||
return base(m);
|
||
} };
|
||
document.body.appendChild(fresh);
|
||
const t0 = Date.now();
|
||
while (!fresh._serverCfg && Date.now() - t0 < 6000) await new Promise((r) => setTimeout(r, 60));
|
||
out.seeded = fresh._decorStyle.color === '#8b0000'
|
||
&& fresh._decorStyle.widthCm === 5
|
||
&& fresh._decorStyle.fillColor === '#607d8b'; // частичный ключ наследует дефолт
|
||
fresh.remove();
|
||
return out;
|
||
});
|
||
checkAll(res, ['decorMode', 'hasRuntime', 'instantStyle', 'noEagerWrite',
|
||
'stillNoWriteBeforeDebounce', 'oneWrite',
|
||
'writeCarriesKey', 'defaultRemovesKey', 'seeded']);
|
||
await finish(browser);
|