diff --git a/homeassistant/www/audi-dashboard-app.js b/homeassistant/www/audi-dashboard-app.js index ee0df3e..5c02f2b 100644 --- a/homeassistant/www/audi-dashboard-app.js +++ b/homeassistant/www/audi-dashboard-app.js @@ -553,12 +553,22 @@ function standortErfassen() { USER_POS_TS = Date.now(); USER_POS_FEHLER = null; standortAnsichtAktualisieren(); }, - (err) => { USER_POS_FEHLER = err.code === err.PERMISSION_DENIED ? "Standortzugriff verweigert" : "Standort nicht verfügbar"; standortAnsichtAktualisieren(); }, + (err) => { + USER_POS_FEHLER = err.code === err.PERMISSION_DENIED ? "Standortzugriff verweigert" : "Standort nicht verfügbar"; + // Auch der Fehlschlag zaehlt als Versuch. Ohne diese Zeile greift die + // Drossel in standortErfassenFallsNoetig() nie, solange der Nutzer die + // Freigabe verweigert - und jedes Backend-Update loeste eine neue + // Hochgenauigkeits-Abfrage aus. + USER_POS_TS = Date.now(); + standortAnsichtAktualisieren(); + }, { enableHighAccuracy: true, timeout: 10000, maximumAge: 30000 } ); } function standortErfassenFallsNoetig() { - if (USER_POS && Date.now() - USER_POS_TS < 30000) return; + // Auf USER_POS_TS statt auf USER_POS pruefen: sonst waere ein fehlgeschlagener + // Versuch kein Versuch, siehe Fehlerpfad oben. + if (USER_POS_TS && Date.now() - USER_POS_TS < 30000) return; standortErfassen(); } @@ -579,7 +589,12 @@ async function standortAdresseAufloesen(lat, lon) { 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 || ""; } catch (e) { + // Den Schluessel bewusst NICHT setzen: sonst gilt ein einzelner + // fehlgeschlagener Abruf (Rate-Limit, kurzer Netzausfall) fuer diese Zelle + // die ganze Sitzung lang als "schon versucht", und es blieben dauerhaft nur + // die Koordinaten stehen. STANDORT_ADRESSE = null; + return null; } STANDORT_ADRESSE_KEY = key; return STANDORT_ADRESSE; @@ -722,12 +737,29 @@ function standortMenuVerdrahten() { ROOT.addEventListener("pointerup", (e) => { if (smY0 === null) return; const dy = e.clientY - smY0; - const el = standortMenuElement(); - if (el) { el.style.transition = ""; el.style.transform = ""; } - smY0 = null; + standortMenuGesteBeenden(); if (Math.abs(dy) > 40) { dy < 0 ? standortMenuOeffnen() : standortMenuSchliessen(); } else standortMenuUmschalten(); }); + /* Ohne pointercancel bleibt smY0 gesetzt, sobald das System die Beruehrung + uebernimmt (iOS-Randgeste, Multitouch, eingehender Anruf). Der + pointermove-Handler oben ruft dann preventDefault() fuer jede weitere + Bewegung - Scrollen waere in der ganzen App blockiert, bis irgendwo ein + pointerup kommt, der dann ein dy aus einem veralteten Startpunkt + auswertet. Die drei anderen Zeigergesten der Datei machen das laengst + richtig. */ + ROOT.addEventListener("pointercancel", () => { + if (smY0 === null) return; + standortMenuGesteBeenden(); + }); +} + +/* Setzt den Gestenzustand zurueck und gibt das Blatt wieder an die + CSS-Uebergaenge ab - gemeinsam von pointerup und pointercancel genutzt. */ +function standortMenuGesteBeenden() { + const el = standortMenuElement(); + if (el) { el.style.transition = ""; el.style.transform = ""; } + smY0 = null; } function standortKachel() { @@ -2924,6 +2956,11 @@ function render() { b.classList.toggle("on", !istTab(route.name)); v.scrollTop = gleicheAnsicht ? merkeScroll : 0; letzteAnsicht = route.name + "|" + (route.id || ""); + /* Die Karten haengen an DOM-Knoten, die render() ueber v.innerHTML gerade + ersetzt hat - eine ueberlebende Leaflet-Instanz zeigte danach auf ein + abgehaengtes Element und bliebe leer. Sie muessen deshalb bei jedem + Durchlauf neu aufgebaut werden; die Haeufigkeit begrenzt stattdessen die + Aenderungspruefung in datenLaden(). */ if (MAP) { MAP.remove(); MAP = null; TILE = null; } if (route.name === "trip" || route.name === "fill") initMap().catch(() => {}); // ohne Internet bleibt die Kartenflaeche leer if (SMAP) { SMAP.remove(); SMAP = null; SMAP_TILE = null; FAHRZEUG_MARKER = null; USER_MARKER = null; } @@ -3874,7 +3911,12 @@ class AudiDashboardPanel extends HTMLElement { } disconnectedCallback() { - if (MAP) { MAP.remove(); MAP = null; } + // Alle drei Karten, nicht nur MAP: sonst bleibt beim Abhaengen des Panels + // (Standort- oder Uebersichtsseite offen) eine Leaflet-Instanz samt ihrem + // window-Resize-Horcher und laufenden Kachelabrufen am Leben. + if (MAP) { MAP.remove(); MAP = null; TILE = null; } + if (SMAP) { SMAP.remove(); SMAP = null; SMAP_TILE = null; FAHRZEUG_MARKER = null; USER_MARKER = null; } + if (TMAP) { TMAP.remove(); TMAP = null; TMAP_TILE = null; } } _aufbauen() {