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:
@@ -1 +1 @@
|
||||
{"version":"2026.8.30.9","sha256":"63b67b2116bdc2970ebcb9c02dc8c2d1ec1f0156fd70c59f88db101307054474","bytes":256695,"gebaut":"2026-08-30T21:09:06Z"}
|
||||
{"version":"2026.8.30.10","sha256":"0a9cdbbccf4e91b07152699e0331bf75ff62908832880e6c2408981b76347710","bytes":257008,"gebaut":"2026-08-30T21:20:20Z"}
|
||||
Binary file not shown.
@@ -786,6 +786,10 @@ function standortErfassenFallsNoetig() {
|
||||
dokumentierte Leaflet-über-CDN-Vorgehen (siehe AGENTS.md). Cache-Schlüssel
|
||||
auf 3 Nachkommastellen (~110 m) gerundet, damit ein erneutes Öffnen an
|
||||
derselben Stelle keinen zweiten Abruf auslöst. */
|
||||
/* Arten, bei denen der Eigenname aussagekraeftiger ist als die Anschrift. */
|
||||
const PLATZ_ARTEN = new Set(["parking", "parking_space", "parking_entrance",
|
||||
"bicycle_parking", "motorcycle_parking", "rest_area", "services", "fuel",
|
||||
"charging_station"]);
|
||||
async function standortAdresseAufloesen(lat, lon) {
|
||||
const key = lat.toFixed(3) + "," + lon.toFixed(3);
|
||||
if (STANDORT_ADRESSE_KEY === key) return STANDORT_ADRESSE;
|
||||
@@ -808,7 +812,16 @@ async function standortAdresseAufloesen(lat, lon) {
|
||||
const daten = await res.json();
|
||||
const a = daten.address || {};
|
||||
const strasse = [a.road, a.house_number].filter(Boolean).join(" ");
|
||||
STANDORT_ADRESSE = [strasse, [a.postcode, a.city || a.town || a.village].filter(Boolean).join(" ")].filter(Boolean).join(", ") || daten.display_name || "";
|
||||
const ort = [a.postcode, a.city || a.town || a.village].filter(Boolean).join(" ");
|
||||
/* Steht das Auto auf einem benannten Platz - Parkplatz, Parkhaus,
|
||||
Rastplatz -, sagt dessen Name mehr als die naechstgelegene Hausnummer.
|
||||
Nominatim liefert ihn im Feld name; die Pruefung auf die Art der
|
||||
Flaeche verhindert, dass jedes zufaellig benannte Gebaeude die
|
||||
Anschrift verdraengt. */
|
||||
const platz = PLATZ_ARTEN.has(daten.type) ? (daten.name || "").trim() : "";
|
||||
STANDORT_ADRESSE = platz
|
||||
? [platz, ort].filter(Boolean).join(", ")
|
||||
: [strasse, ort].filter(Boolean).join(", ") || daten.display_name || "";
|
||||
} catch (e) {
|
||||
// Den Schluessel bewusst NICHT setzen: sonst gilt ein einzelner
|
||||
// fehlgeschlagener Abruf (Rate-Limit, kurzer Netzausfall) fuer diese Zelle
|
||||
@@ -4803,32 +4816,16 @@ function ereignisseVerdrahten() {
|
||||
ROOT.addEventListener("pointerdown", (e) => {
|
||||
// Ziehen zum Aktualisieren (nur Übersicht, nur wenn ganz oben gescrollt) -
|
||||
// unabhängig von der Wischgeste unten, da hier keine .swipe-wrap nötig ist.
|
||||
if (e.isPrimary && route.name === "home" && !ptrLaedt) {
|
||||
const ansicht = $("#view");
|
||||
if (ansicht && ansicht.scrollTop <= 0) { ptrY0 = e.clientY; ptrDrag = 0; }
|
||||
}
|
||||
// Nur Maus/Stift. Der Finger laeuft ueber die Touch-Ereignisse weiter
|
||||
// unten, weil nur dort preventDefault() das native Ueberscrollen wirklich
|
||||
// verhindert - siehe ptrBewegen().
|
||||
if (e.isPrimary && e.pointerType !== "touch") ptrStarten(e.clientY);
|
||||
const wrap = e.target.closest(".swipe-wrap");
|
||||
if (!wrap || !e.isPrimary) return;
|
||||
swipeAktivWrap = wrap; swipeStartX = e.clientX; swipeStartY = e.clientY; swipeGeste = null; swipeDX = 0;
|
||||
});
|
||||
ROOT.addEventListener("pointermove", (e) => {
|
||||
if (ptrY0 !== null && e.isPrimary) {
|
||||
const ansicht = $("#view"), dy = e.clientY - ptrY0;
|
||||
if (dy > 0 && ansicht && ansicht.scrollTop <= 0) {
|
||||
e.preventDefault();
|
||||
ptrDrag = Math.min(90, dy * 0.5); // Widerstand, wie bei iOS
|
||||
const ptr = $("#ptr");
|
||||
if (ptr) {
|
||||
ptr.style.transition = "none";
|
||||
ptr.style.height = ptrDrag + "px";
|
||||
ptr.querySelector("span").textContent = ptrDrag >= 56 ? "Loslassen zum Aktualisieren" : "Ziehen zum Aktualisieren";
|
||||
}
|
||||
} else {
|
||||
ptrY0 = null; ptrDrag = 0;
|
||||
const ptr = $("#ptr");
|
||||
if (ptr) { ptr.style.transition = ""; ptr.style.height = "0"; }
|
||||
}
|
||||
}
|
||||
if (e.pointerType !== "touch") ptrBewegen(e.clientY);
|
||||
if (!swipeAktivWrap || !e.isPrimary) return;
|
||||
const dx = e.clientX - swipeStartX, dy = e.clientY - swipeStartY;
|
||||
if (swipeGeste === null) {
|
||||
@@ -4863,6 +4860,39 @@ function ereignisseVerdrahten() {
|
||||
// auf den gerade erst aufgedeckten Löschen-Knopf) fälschlich verschluckt.
|
||||
if (swipeWarGezogen) setTimeout(() => { swipeWarGezogen = false; }, 0);
|
||||
}
|
||||
function ptrStarten(y) {
|
||||
if (route.name !== "home" || ptrLaedt) return;
|
||||
const ansicht = $("#view");
|
||||
if (ansicht && ansicht.scrollTop <= 0) { ptrY0 = y; ptrDrag = 0; }
|
||||
}
|
||||
/* Gibt true zurueck, wenn die Geste uns gehoert - der Aufrufer muss dann
|
||||
preventDefault() rufen. Warum das ueber Touch-Ereignisse laufen muss:
|
||||
preventDefault() auf einem Pointer-Ereignis verhindert laut Spezifikation
|
||||
KEIN Scrollen; darueber entscheidet allein touch-action. Auf einem echten
|
||||
Touch-Geraet uebernimmt der Browser die senkrechte Geste deshalb sofort,
|
||||
schickt pointercancel und stellt pointermove ein - die Geste wurde
|
||||
zurueckgesetzt, bevor sie die 56px erreichen konnte. Am Rechner faellt das
|
||||
nie auf, weil eine Maus keine Scroll-Uebernahme kennt; auch synthetische
|
||||
PointerEvents durchlaufen sie nicht. Auf touchmove dagegen wirkt
|
||||
preventDefault() und haelt das native Ueberscrollen an. */
|
||||
function ptrBewegen(y) {
|
||||
if (ptrY0 === null) return false;
|
||||
const ansicht = $("#view"), dy = y - ptrY0;
|
||||
if (dy > 0 && ansicht && ansicht.scrollTop <= 0) {
|
||||
ptrDrag = Math.min(90, dy * 0.5); // Widerstand, wie bei iOS
|
||||
const ptr = $("#ptr");
|
||||
if (ptr) {
|
||||
ptr.style.transition = "none";
|
||||
ptr.style.height = ptrDrag + "px";
|
||||
ptr.querySelector("span").textContent = ptrDrag >= 56 ? "Loslassen zum Aktualisieren" : "Ziehen zum Aktualisieren";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
ptrY0 = null; ptrDrag = 0;
|
||||
const ptr = $("#ptr");
|
||||
if (ptr) { ptr.style.transition = ""; ptr.style.height = "0"; }
|
||||
return false;
|
||||
}
|
||||
function ptrBeenden() {
|
||||
if (ptrY0 === null) return;
|
||||
ptrY0 = null;
|
||||
@@ -4886,6 +4916,19 @@ function ereignisseVerdrahten() {
|
||||
ROOT.addEventListener("pointerup", (e) => { swipeBeenden(); ptrBeenden(); });
|
||||
ROOT.addEventListener("pointercancel", (e) => { swipeBeenden(); ptrBeenden(); });
|
||||
|
||||
// Ziehen zum Aktualisieren auf dem Finger: eigener Weg ueber Touch-Ereignisse
|
||||
// (Begruendung in ptrBewegen()). passive:false ist zwingend - ohne das ist
|
||||
// preventDefault() auf touchmove wirkungslos und der Browser scrollt doch.
|
||||
ROOT.addEventListener("touchstart", (e) => {
|
||||
if (e.touches.length === 1) ptrStarten(e.touches[0].clientY);
|
||||
}, { passive: true });
|
||||
ROOT.addEventListener("touchmove", (e) => {
|
||||
if (e.touches.length !== 1) return;
|
||||
if (ptrBewegen(e.touches[0].clientY)) e.preventDefault();
|
||||
}, { passive: false });
|
||||
ROOT.addEventListener("touchend", () => ptrBeenden());
|
||||
ROOT.addEventListener("touchcancel", () => ptrBeenden());
|
||||
|
||||
// Batteriespannungs-Verlauf: Pinch-Zoom (2 Finger) / Ziehen zum Verschieben
|
||||
// (1 Finger) / Mausrad-Zoom, per pointerId in bvZeiger nachverfolgt statt
|
||||
// über die swipe*-Variablen oben, die für horizontales Wischen in Listen
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "audi_dashboard",
|
||||
"name": "Audi Dashboard",
|
||||
"version": "2026.8.30.9",
|
||||
"version": "2026.8.30.10",
|
||||
"documentation": "https://gitea.nothaft.cloud/paul/audi-app/src/branch/main/README.md",
|
||||
"issue_tracker": "https://gitea.nothaft.cloud/paul/audi-app/issues",
|
||||
"codeowners": ["@paul"],
|
||||
|
||||
Reference in New Issue
Block a user