feat v1.20.0: rooms may not overlap

- A click strictly inside an existing room is refused while drawing; a click ON a wall
  stays legal (neighbours share walls, and real walls overlap collinearly rather than
  match exactly, so vertices land on existing outlines mid-span constantly).
- Closing an outline that overlaps an existing room is refused — vertex checks alone are
  not enough, an outline drawn AROUND a room has every vertex outside it. Nesting counts
  as overlap. The outline stays open so it can be corrected.
- New pure geometry: roomPoly, pointOnBoundary, pointStrictlyInside, segmentsProperlyCross
  (touching/collinear deliberately not a crossing), roomsOverlap. +4 tests (67).
Verified live: all 15 existing neighbour pairs stay clean (no false positives).
This commit is contained in:
Matysh
2026-07-16 07:59:01 +03:00
parent 65268a7985
commit 1552bff99a
13 changed files with 264 additions and 82 deletions
+13
View File
@@ -1,5 +1,18 @@
# Changelog
## v1.20.0 — 2026-07-16 (rooms may not overlap)
- **A click strictly inside an existing room is refused** while drawing (toast names the room).
Being *on* a wall stays legal — neighbouring rooms share walls, and real walls overlap
collinearly rather than match exactly, so new vertices land on existing outlines mid-span
all the time. `pointStrictlyInside` excludes the boundary explicitly (ray casting alone is
unreliable exactly on an edge).
- **Closing an outline that overlaps an existing room is refused** — vertex checks alone are not
enough: an outline drawn *around* a room has every vertex outside it. The outline stays open
so it can be corrected. Nesting one room inside another counts as an overlap.
- New pure geometry in logic.ts: `roomPoly`, `pointOnBoundary`, `pointStrictlyInside`,
`segmentsProperlyCross` (touching/collinear is deliberately not a crossing), `roomsOverlap`
(edge crossings + containment probe, which also catches duplicate outlines). (+4 tests: 63 → 67.)
## 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
+2 -2
View File
@@ -13,14 +13,14 @@
| Item | State |
|---|---|
| Version | **v1.19.0** everywhere (manifest, const.py, package.json, CARD_VERSION) |
| Version | **v1.20.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 | 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) |
| Tests | 67 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)
+3
View File
@@ -71,6 +71,9 @@ Run the *core flows* (marked ★ below) in each environment at least once per mi
- [ ] 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)
- [ ] Rooms never overlap (v1.20.0): a click strictly inside an existing room is refused with a
toast; a click ON a shared wall (including mid-span of a longer neighbour wall) still works
- [ ] Closing an outline drawn AROUND an existing room is refused; the outline stays open
- [ ] 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