Ziehen zum Aktualisieren, Nachtmodus-Zeilen, Parkplatznamen (2026.8.30.10)

Ziehen zum Aktualisieren funktionierte auf keinem Geraet, in keiner der
beiden Anwendungen - und der Grund entwertet zugleich, wie es bisher geprueft
wurde. Beide trieben die Geste ueber pointermove und riefen dort
preventDefault(). Das verhindert laut Spezifikation kein Scrollen; darueber
entscheidet allein touch-action. Auf echtem Touch uebernimmt der Browser die
senkrechte Geste, schickt pointercancel und stellt pointermove ein - der Zug
wird zurueckgesetzt, lange bevor er die Schwelle erreicht. Eine Maus kennt
diese Uebernahme nicht, synthetische PointerEvents ebenso wenig: genau
deshalb lief die Geste 2026-08-17 im Test sauber durch und am Geraet nie.

Jetzt laeuft sie auf Touch-Ereignissen, touchmove zwingend mit passive:false
(sonst ist preventDefault() wirkungslos); der Zeigerweg bleibt fuer Maus und
Stift und ignoriert pointerType "touch". Mit echten TouchEvents geprueft,
inklusive defaultPrevented - dem einzigen Signal, das belegt, dass das native
Ueberscrollen wirklich unterbunden ist.

Der zuletzt nicht nachstellbare Befund war nachtmodus-spezifisch: --tile ist
dort ein durchscheinender Schleier, und die Wischzeilen malten ihn ein
zweites Mal auf die Kachel, auf der sie ohnehin liegen. Am Tag sind beide
deckend weiss, deshalb war nichts zu sehen. Das Panel nutzt an dieser Stelle
--tile-deckend; dieses Token fehlte im Design-System und ist jetzt da.

Ausserdem: steht das Auto auf einem benannten Platz, zeigen beide dessen
Namen statt der naechsten Hausnummer - Nominatim liefert ihn mit, die
Pruefung auf die Art der Flaeche verhindert, dass irgendein benanntes
Gebaeude die Anschrift verdraengt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 23:22:52 +02:00
parent a08922e9a0
commit 0fd81df700
9 changed files with 224 additions and 45 deletions
+52 -1
View File
@@ -1,7 +1,7 @@
# AGENTS.md — Project state, review findings, open items, and working rules
**Last updated: 2026-08-30** (owner findings batch - vehicle pin, tile chevrons, select arrows,
SmartDeal dialog, address cache and pull-to-refresh; manifest `2026.8.30.9`, see section AO.
SmartDeal dialog, address cache and pull-to-refresh; manifest `2026.8.30.10`, see section AO.
Before that: design-audit follow-through - the five priority items applied to
both codebases, plus the location preview's wrong pin; manifest `2026.8.30.8`, see section AN.
Before that: third parity round — the panel had never actually rendered Audi
@@ -5879,6 +5879,57 @@ vs 1.1 right, measured via `getBBox`) and is now nudged onto centre and scaled t
outweighing its outline neighbours; Teilen uses the real `share-s` from the CI set; and the sheet's
close button only exists while the sheet is raised - half-covered it looked operable and did nothing.
**The "could not be reproduced" finding was a night-mode-only defect (2026.8.30.10).** The owner
added the missing detail: night mode. In night mode `--tile` is deliberately translucent - a white
veil over the dark page - and `.ads-swipe-content` painted the same token a second time on top of
the tile it already sits on. Two veils add up, so every row in Fahrten and Tanken was visibly lighter
than the tile around it, while the year and month headers (not swipe rows) stayed correct. In day
mode both values are opaque white, which is why painting white on white showed nothing and the first
pass found the two sides identical. The panel does not have this: its iOS overlay sets
`.swipe-wrap .swipe-content{background:var(--tile-deckend)}`, an opaque token that `design-system`
never had. Added `--tile-deckend` (#171B21 / #FFFFFF, the panel's own values) and switched
`SwipeRow.css` to it. **Rule worth keeping: any surface painted on top of another surface needs the
opaque token, never `--tile`** - the bug is invisible in day mode by construction.
**Pull-to-refresh never worked on a real device, in either app - and the reason invalidates how it
was verified before.** Both implementations drove the gesture from `pointermove` and called
`preventDefault()` there. Per the Pointer Events spec that does **not** prevent scrolling: scrolling
is decided by `touch-action` alone. On a real touch screen the browser claims the vertical gesture,
fires `pointercancel` and stops sending `pointermove`; the handler's own cancel path then resets the
drag long before the 56px threshold. A mouse never triggers that takeover, and neither do synthetic
`PointerEvent`s - which is precisely why the 2026-08-17 session drove the whole gesture end to end
with dispatched pointer events, saw it work, and concluded the JS was fine. It was fine; it was
attached to the wrong event family. The `overscroll-behavior-y: contain` added then addresses scroll
*chaining* to the host page, a different problem, and was left in place.
Both now run the gesture on touch events - `touchstart` passive, `touchmove` with
**`{ passive: false }`** (without that flag `preventDefault()` is ignored and the browser scrolls
anyway), `touchend`/`touchcancel` - while the pointer path stays for mouse and stylus and now
ignores `pointerType === "touch"` so the two cannot fight over the same gesture. Panel: `ptrStarten()`
/ `ptrBewegen()` / `ptrBeenden()` extracted so both paths share one implementation. App: a manual
listener in a `useEffect`, because React registers `touchmove` passively and `preventDefault()` in an
`onTouchMove` prop would be silently ignored. Verified in both with genuine `TouchEvent`s - which the
old code could not have satisfied: threshold reached, label switching to "Loslassen zum
Aktualisieren", the refresh running, and `defaultPrevented === true` on the move, the one signal that
proves the native overscroll is actually suppressed.
One trap avoided while doing it: the app's early `return` for the wide layout sat in front of the new
`useEffect`, which would have made the hook run on some renders and not others. Moved behind it.
**Named places instead of a street address.** On the owner's question - a car park says more than the
nearest house number. Nominatim already returns `name` plus the type of the matched feature; both
apps now prefer that name when the type is one of parking / parking_space / parking_entrance /
bicycle_parking / motorcycle_parking / rest_area / services / fuel / charging_station, with the town
still appended. The type check is what keeps any incidentally named building from displacing the
address. And to answer the other half plainly: when nothing resolves at all, both show the
coordinates - that was already the designed fallback (`adresse ?? koordinaten`), and it is also what
a throttled lookup produces, which is exactly why the two cases were indistinguishable before the
cache landed.
**Header padding on the app was cut to the safe area on the owner's instruction** - see the note at
the end of section AN; the panel's 56px sit below Home Assistant's own header, the native shell has
nothing above them but the status bar.
**One finding could not be reproduced:** "Fahrten/Tankfüllung: Auflistung/grauer Hintergrund ist
falsch". Panel and app are identical there - same backgrounds (transparent rows on a white tile),
same paddings, same indents, same text. Reported back rather than guessed at.