mirror of
https://github.com/Matysh/houseplan-card
synced 2026-07-31 08:28:31 +00:00
feat v1.19.0: a line is never an entity of its own — walls are derived from rooms
A wall can only exist as an edge of a closed room: - roomEdges(rooms) derives walls from room outlines, deduping shared ones, so deleting a room keeps the borders its neighbours still contribute and drops the rest — the rule falls out of the model instead of needing bookkeeping. - Nothing is persisted while drawing: an outline you never close leaves no lines behind (previously every click pair was written to space.segments immediately). - The 'Erase line' tool is gone; space.segments is stripped on every save (validation still tolerates it on read so a stale tab cannot fail a save). - Dead code out: _addSegment/_removeSegmentByKey/_distToSeg/_pathSegs/_segKey. Docs (ARCHITECTURE/TESTING/CHANGELOG) updated in the same commit. +2 tests (63).
This commit is contained in:
+13
-3
@@ -111,12 +111,22 @@ If the server config is empty, the card falls back to the legacy bundle (the dac
|
||||
|
||||
## Markup editor (v1.4.0+)
|
||||
|
||||
State inside the card: `_markup` (mode), `_tool` (draw/erase/delroom), `_path` (the current outline,
|
||||
vertices on the GRID_N=60 grid). Clicks on the stage → `_svgPoint`→`_snap`. Each pair of points adds a
|
||||
segment to `space.segments` (dedup by key, saved via config/set with debounce). The outline is closed
|
||||
State inside the card: `_markup` (mode), `_tool` (draw/delroom), `_path` (the current outline,
|
||||
vertices on the GRID_N=240 grid). Clicks on the stage → `_svgPoint`→`_snap`. The outline is closed
|
||||
= a click on the first vertex → area select (hass.areas) + name → room {poly}. Polygon rooms and
|
||||
rectangles are rendered uniformly (hit-test: point-in-polygon / rect).
|
||||
|
||||
**A line is never an entity of its own (v1.19.0).** Nothing is persisted while you draw: an
|
||||
outline you never close leaves no trace. Walls are *derived* from the room outlines by
|
||||
`roomEdges(rooms)` (logic.ts) and deduped by `segKey`, so a wall shared by two rooms is emitted
|
||||
once — deleting a room therefore keeps the borders its neighbours still contribute and drops the
|
||||
rest, with no bookkeeping. The legacy `space.segments` array is stripped on every save (validation
|
||||
still tolerates it on read; see CHANGELOG v1.19.0).
|
||||
|
||||
While drawing, the length of the current segment follows the cursor (`_fmtLen` → `segmentCm`/
|
||||
`formatLength`): metres, or feet+inches when `hass.config.unit_system` is imperial. The scale is
|
||||
per-space `cell_cm` — cm represented by one grid cell (default 5, so 240 cells ≈ 12 m).
|
||||
|
||||
## Integration WS API
|
||||
|
||||
| Command | Parameters | Response |
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
# Changelog
|
||||
|
||||
## v1.19.0 — 2026-07-16 (a line is never a thing of its own)
|
||||
**Model change.** A wall can only exist as an edge of a closed room. Consequences:
|
||||
- **Walls are derived from room outlines** (`roomEdges` in logic.ts), not stored. A wall
|
||||
shared by two rooms is emitted once, so **deleting a room keeps the borders its neighbours
|
||||
still contribute** — and drops the walls nobody else uses. This falls out of the model
|
||||
instead of needing bookkeeping.
|
||||
- **An abandoned outline leaves nothing behind.** Previously every click pair was written to
|
||||
`space.segments` immediately, so a contour you never closed left orphan lines on the plan.
|
||||
Now nothing is persisted until the room is saved.
|
||||
- **The "Erase line" tool is gone** — there is no standalone line to erase. Mis-clicks are
|
||||
undone with Esc / Ctrl+Z as before.
|
||||
- **`space.segments` is dropped on every save** (legacy configs shed it on first write).
|
||||
Validation still tolerates the field so a stale browser tab cannot fail a save; diagnostics
|
||||
no longer reports it. Lines that belonged to no room disappear on upgrade — by design.
|
||||
- Dead code removed: `_addSegment`, `_removeSegmentByKey`, `_distToSeg`, `_pathSegs`, `_segKey`.
|
||||
`segKey(a, b, prec)` gained a precision argument (normalized coords need more than render
|
||||
units). (+2 tests: 61 → 63.)
|
||||
|
||||
## v1.18.1 — 2026-07-16 (fix: the drawing ruler was invisible)
|
||||
- Fix on top of v1.18.0: the length badge never showed up while drawing. It was rendered
|
||||
inside `.devlayer`, and `.stage.markup .devlayer { display: none }` hides that whole layer
|
||||
|
||||
+2
-2
@@ -13,14 +13,14 @@
|
||||
|
||||
| Item | State |
|
||||
|---|---|
|
||||
| Version | **v1.18.1** everywhere (manifest, const.py, package.json, CARD_VERSION) |
|
||||
| Version | **v1.19.0** everywhere (manifest, const.py, package.json, CARD_VERSION) |
|
||||
| GitHub | https://github.com/Matysh/houseplan-card — branch `main`, releases v1.9.3…v1.11.2 |
|
||||
| CI | `.github/workflows/validate.yml` (hacs + hassfest + frontend + backend) — **fully green** since v1.11.1; `release.yml` auto-attaches the card bundle (needs `permissions: contents: write`, fixed) |
|
||||
| HACS | Works as custom repository (id 1290210112 on the home instance). **Inclusion PR: https://github.com/hacs/default/pull/9004** (queue ≈2 months as of 2026-07). Lesson: #8995 was auto-closed by hacs-bot — the PR body MUST be their exact template with every checkbox ticked and all 3 links (release, HACS action run, hassfest run); a custom body gets closed without discussion |
|
||||
| Brands | Ships **inside the integration**: `custom_components/houseplan/brand/{icon,icon@2x,logo,logo@2x}.png` (HA ≥2026.3 local-brands mechanism). home-assistant/brands PR #10700 was auto-closed — that repo no longer accepts custom integrations |
|
||||
| Home instance | ha.jbstudio.pro (SSH port 323, key `ha_jb`), deployed v1.11.2, installed *via HACS* (custom repo) — updates flow through HACS now |
|
||||
| Localization | UI en/ru (`src/i18n.ts`), auto by `hass.locale` + `language` card option; codebase and docs are English-first (`README.ru.md` is the Russian copy) |
|
||||
| Tests | 61 frontend (node:test, incl. a 12-test buildDevices suite on a fake hass) + 10 pure backend (anywhere) + 12 HA-harness backend (CI only, py3.13; skipped locally — sandbox has py3.10) |
|
||||
| Tests | 63 frontend (node:test, incl. a 12-test buildDevices suite on a fake hass) + 10 pure backend (anywhere) + 12 HA-harness backend (CI only, py3.13; skipped locally — sandbox has py3.10) |
|
||||
|
||||
## Recent milestones (details in CHANGELOG.md)
|
||||
|
||||
|
||||
+8
-1
@@ -63,7 +63,14 @@ Run the *core flows* (marked ★ below) in each environment at least once per mi
|
||||
|
||||
## Room markup editor ★
|
||||
|
||||
- [ ] Grid appears; dots snap; segments draw pair-by-pair; shared walls reused
|
||||
- [ ] Grid appears; dots snap; the outline draws pair-by-pair; shared walls reused
|
||||
- [ ] Ruler: while drawing, the length of the current segment follows the cursor
|
||||
(metres, or feet+inches on an imperial HA); scale = space "cm per cell" (default 5)
|
||||
- [ ] A line cannot exist on its own: start an outline, do NOT close it, leave markup —
|
||||
no lines are left behind (nothing was written to the config)
|
||||
- [ ] Deleting a room removes its walls, EXCEPT those shared with a neighbouring room
|
||||
(the neighbour still yields them); deleting the neighbour too removes them as well
|
||||
- [ ] There is no "Erase" tool in the markup toolbar (removed in v1.19.0)
|
||||
- [ ] Esc / Ctrl+Z removes the last dot (and its line); Reset clears the path
|
||||
- [ ] Closing the contour (click the first dot, ≥4 points) opens the room dialog
|
||||
- [ ] Room dialog: area list shows only unassigned areas; picking an area prefills the name
|
||||
|
||||
Reference in New Issue
Block a user