Befundliste des Besitzers: drei echte Fehler, dazu Feinschliff (2026.8.30.9)

Fahrzeug-Pin auf der Standortkarte fehlte: die Marker-Effekte lesen Refs,
die erst im asynchronen Leaflet-Import gesetzt werden. Beim ersten Lauf leer,
Effekt steigt aus - und weil die Koordinaten sich danach nicht mehr aendern,
lief er nie wieder. Ein Bereitschaftsschalter in den Abhaengigkeiten behebt
das fuer Marker, Kachelebene und eigene Position zugleich.

Kachelpfeil auf "Mein Audi" sass auf halber Kachelhoehe statt oben neben der
Ueberschrift; Auswahlfelder hatten nach appearance:none ueberhaupt keinen
Aufklapp-Pfeil mehr.

SmartDeal: das Datumsfeld war fehlerhaft und die Abfrage, bis wann der Rabatt
gilt, fehlte ganz. Das Panel fragt beim Einschalten und zeigt danach nur an -
genau daran haengt, dass der Rabatt von selbst auslaufen kann. Portiert.

Adressen statt Koordinaten: Nominatim drosselt uns inzwischen. Beide Apps
fielen korrekt zurueck, merkten sich Treffer aber nur bis zum Neuladen. Jetzt
dauerhaft im selben Cache wie die Tankstellensuche.

Ziehen zum Aktualisieren auf dem Geraet: dem Scrollbehaelter fehlte
overscroll-behavior, das native Overscroll nahm die Geste weg - derselbe
Befund, den das Panel am 2026-08-17 hatte.

Ausserdem: Platzhalter wieder in voller Groesse, FIN statt Fahrgestellnummer,
Details als Hinweiszeile, Chevron an der Batteriespannung, Reifenzeile
"aktuell montiert:", Zahnrad statt Stift am Anzugsmoment, Radkilometer in der
Zahlenschrift, Layer-Icon zentriert, share-s beim Teilen, Schliessen-Knopf nur
bei aufgezogener Karte.

Nicht nachstellbar und zurueckgemeldet: "Fahrten/Tanken, grauer Hintergrund" -
Panel und App sind dort deckungsgleich.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-30 23:12:33 +02:00
parent f38907991d
commit a08922e9a0
16 changed files with 396 additions and 110 deletions
@@ -1 +1 @@
{"version":"2026.8.30.8","sha256":"2754d426c7145d000fd2194d4dd85db096c2fcae008eb518584f189becfb0538","bytes":256098,"gebaut":"2026-08-30T16:30:51Z"}
{"version":"2026.8.30.9","sha256":"63b67b2116bdc2970ebcb9c02dc8c2d1ec1f0156fd70c59f88db101307054474","bytes":256695,"gebaut":"2026-08-30T21:09:06Z"}
@@ -789,6 +789,20 @@ function standortErfassenFallsNoetig() {
async function standortAdresseAufloesen(lat, lon) {
const key = lat.toFixed(3) + "," + lon.toFixed(3);
if (STANDORT_ADRESSE_KEY === key) return STANDORT_ADRESSE;
/* Dauerhafter Cache im selben Fach wie die Tankstellensuche, Schluessel mit
"rev:"-Vorsatz. Bis 2026-08-30 lag hier nur ein einziger Punkt im
Arbeitsspeicher, weg beim naechsten Neuladen - mit der Begruendung, die
Fahrzeugposition aendere sich ohnehin laufend. Das stimmt fuers Fahren,
nicht fuers Parken: das Auto steht meist an denselben Stellen, und wenn
Nominatim gerade drosselt, stand an einer laengst bekannten Stelle
wieder nur ein Koordinatenpaar. */
const cacheKey = "rev:" + key;
const cache = geoCacheLesen();
if (typeof cache[cacheKey] === "string") {
STANDORT_ADRESSE = cache[cacheKey];
STANDORT_ADRESSE_KEY = key;
return STANDORT_ADRESSE;
}
try {
const res = await fetch(`https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=${lat}&lon=${lon}&zoom=18&addressdetails=1`, { headers: { "Accept-Language": "de" } });
const daten = await res.json();
@@ -804,6 +818,9 @@ async function standortAdresseAufloesen(lat, lon) {
return null;
}
STANDORT_ADRESSE_KEY = key;
// Nur echte Treffer merken - eine gedrosselte Antwort ist kein "hier gibt es
// keine Adresse" und soll beim naechsten Mal erneut versucht werden.
if (STANDORT_ADRESSE) geoCacheSchreiben(cacheKey, STANDORT_ADRESSE);
return STANDORT_ADRESSE;
}
function standortAdresseLaden() {
@@ -1081,6 +1098,11 @@ const CI = {
selectAll: '<path fill="currentColor" d="M2.8 2H5v1H3v2H2V2.8a.76.76 0 0 1 .43-.71.9.9 0 0 1 .35-.09zv.5zM9 3H7V2h2zm4 0h-2V2h2zm4 0h-2V2h2zm4 0h-2V2h2.2v.5V2h.02a1 1 0 0 1 .1.01c.07.01.16.03.25.08a.76.76 0 0 1 .43.71V5h-1zM6 6h12v12H6zm1 1v10h10V7zM3 7v2H2V7zm19 0v2h-1V7zM3 11v2H2v-2zm19 0v2h-1v-2zM3 15v2H2v-2zm19 0v2h-1v-2zM3 21v-2H2v2.2a.76.76 0 0 0 .43.71.9.9 0 0 0 .35.09h.01l.01-.5v.5H5v-1zm19-2v2.2a.76.76 0 0 1-.43.71.9.9 0 0 1-.35.09h-.01l-.01-.49V22H19v-1h2v-2zM9 22H7v-1h2zm4 0h-2v-1h2zm4 0h-2v-1h2z"/>',
planRoute: '<path fill="currentColor" d="m18.3 7-3.65-3.65.7-.7 4.86 4.85-4.86 4.85-.7-.7L18.29 8H9.5C8.67 8 8 8.67 8 9.5V21H7V9.5A2.5 2.5 0 0 1 9.5 7z"/>',
upload: '<path fill="currentColor" d="M13 20h-1V9.7l-3.65 3.65-.7-.7 4.85-4.86 4.85 4.86-.7.7L13 9.71zM6 5V4h13v1z"/>',
/* share-l/-s aus dem Audi-CI-Satz (vom Nutzer als SVG geliefert, verbatim
uebernommen) - l im 48er-, s im 24er-Raster wie poi-l/poi-s. Loest beim
Teilen das upload-Icon ab, das dort nur ersatzweise stand. */
shareL: '<path fill="currentColor" d="m23.5 3.8 6.85 6.85-.7.7L24 5.71V29h-1V5.7l-5.65 5.65-.7-.7 6.85-6.86ZM11 16h8v1h-7v23h23V17h-7v-1h8v25H11z"/>',
shareS: '<path fill="currentColor" d="m11.5 1.8 3.85 3.85-.7.7L12 3.71V15h-1V3.7L8.35 6.36l-.7-.7zM5 8h4v1H6v11h11V9h-3.02V8H18v13H5z"/>',
parking: '<path fill="currentColor" d="M0 2.5A2.5 2.5 0 0 1 2.5 0H23v20.5a2.5 2.5 0 0 1-2.5 2.5H0zM2.5 1C1.67 1 1 1.67 1 2.5V22h19.5c.83 0 1.5-.67 1.5-1.5V1zm11.59 6.35C13.6 7 13.02 7 12.5 7H8v6h4.5c.52 0 1.11-.01 1.59-.35.44-.3.91-1 .91-2.65 0-1.66-.47-2.34-.91-2.65M8 14v3H7V6h5.53c.5 0 1.38 0 2.13.53C15.47 7.09 16 8.16 16 10s-.53 2.9-1.34 3.47a3.6 3.6 0 0 1-2.13.53z"/>',
/* battery-12v-l/-s aus dem Audi-CI-Icon-Satz (vom Nutzer als SVG geliefert,
verbatim uebernommen) - l im 48er-, s im 24er-Grid wie poi-l/poi-s. */
@@ -1131,7 +1153,13 @@ function vStandort() {
<div class="kartensteuerung">
<button type="button" data-standort-layer aria-pressed="${SMAP_STIL === "satellit"}"
aria-label="${SMAP_STIL === "satellit" ? "Satellitenansicht, zur Straßenkarte wechseln" : "Straßenkarte, zur Satellitenansicht wechseln"}">
${ciSVG(CI.mapLayer, 22)}
<!-- Das Layer-Symbol ist als einziges der vier Kartenknoepfe nicht mittig in
seinem eigenen 24er-Raster (Rand links 2,1 / rechts 1,1, gemessen ueber
getBBox) und fuellt als gefuellte Form deutlich mehr Flaeche als die drei
Kontur-Nachbarn. Die Verschiebung setzt seinen Mittelpunkt genau auf
(12,12), der Faktor 0,88 nimmt ihm das Uebergewicht - dieselbe Behandlung
wie beim Statistik-Tabsymbol. -->
${ciSVG(CI.mapLayer, 22).replace("<path", '<g transform="translate(1.44 1.44) scale(0.88) translate(-0.55 0.2)"><path').replace("</svg>", "</g></svg>")}
</button>
<button type="button" data-standort-fahrzeug aria-label="Fahrzeug auf der Karte suchen">
${ciSVG(CI.carSearch, 22)}
@@ -1151,9 +1179,13 @@ function vStandort() {
<button type="button" class="standortmenu-griff" data-standort-umschalten
aria-expanded="${STANDORTMENU_OFFEN}" aria-controls="standortmenu"
aria-label="Fahrzeugdetails ${STANDORTMENU_OFFEN ? "einklappen" : "aufklappen"}"></button>
${STANDORTMENU_OFFEN ? `
<!-- Nur im aufgezogenen Zustand. Im halb verdeckten Ruhezustand hat
Schließen nichts zu schließen - der Knopf sah bedienbar aus und
tat nichts. -->
<button type="button" class="standortmenu-schliessen" data-standort-schliessen aria-label="Schließen">
<svg viewBox="0 0 20 20" width="16" height="16" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round"><path d="M5 5l10 10M15 5 5 15"/></svg>
</button>
</button>` : ""}
<div class="standortmenu-kopf">
<div class="standortmenu-name">${esc(CONFIG.fahrzeugtitel)}</div>
<div class="standortmenu-distanz" id="standortDistanz">${distanz}</div>
@@ -1177,7 +1209,7 @@ function vStandort() {
${ciSVG(CI.planRoute, 15)}Route
</a>
<button type="button" class="standort-pille" data-standort-teilen ${bekannt ? "" : "disabled"}>
${ciSVG(CI.upload, 15)}Teilen
${ciSVG(CI.shareS, 15)}Teilen
</button>
</div>
</div>
@@ -1642,8 +1674,10 @@ function vAudi() {
<span class="label">Fahrzeug</span>
<svg class="go" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg>
<dl class="rows" style="margin-top:10px">
<div class="row"><dt>Fahrgestellnummer</dt><dd>${esc(CAR.fin)}</dd></div>
<div class="row"><dt>Details</dt><dd>${esc(CAR.details)}</dd></div>
<div class="row"><dt>FIN</dt><dd>${esc(CAR.fin)}</dd></div>
<!-- Die technischen Daten stehen eine Ebene tiefer (Identität und Technik);
hier nur der Hinweis darauf, statt einer abgeschnittenen Motorzeile. -->
<div class="row"><dt>Details</dt><dd class="row-hinweis">Informationen über das Auto</dd></div>
<div class="row"><dt>Erstzulassung</dt><dd>${esc(CAR.erstzulassung)}</dd></div>
<div class="row"><dt>Ausführung</dt><dd>${CONFIG.ausfuehrung ? esc(CONFIG.ausfuehrung) : "noch offen"}</dd></div>
<div class="row" style="border-bottom:0"><dt>Ausstattung</dt>
@@ -1703,10 +1737,10 @@ function vAudi() {
<span class="label">Reifen</span>
<svg class="go" viewBox="0 0 6 10"><polyline points="1,1 5,5 1,9"/></svg>
<dl class="rows" style="margin-top:10px">
<div class="row"><dt>montiert: ${r.aktiv}räder</dt><dd>${esc(a.mass)}</dd></div>
<div class="row"><dt>aktuell montiert:</dt><dd>${r.aktiv}räder</dd></div>
<div class="row"><dt>Laufleistung</dt><dd>${a.km != null ? de(a.km) + " km" : "unbekannt"}</dd></div>
<div class="row" style="border-bottom:0"><dt>Wechseltermin</dt>
<dd>${dedat(new Date(r.wechsel.datum))}<small>${r.wechsel.vereinbart ? "vereinbart" : ""}</small></dd></div>
<dd>${dedat(new Date(r.wechsel.datum))}${r.wechsel.vereinbart ? "<small>vereinbart</small>" : ""}</dd></div>
</dl></button>`;
}
@@ -444,6 +444,11 @@ button.sicherheitszeile:active { background: var(--tile-2); }
.sicherheitsliste .sicherheitszeile:last-child { border-bottom: 0; }
.sicherheitszeile-text { flex: 1; font-size: 14px; color: var(--fg); }
.sicherheitszeile .chev { margin-left: auto; }
/* Wert als Kommentar statt als Angabe - fuer Zeilen, deren rechte Seite nur
beschreibt, was hinter der Kachel liegt (Mein Audi, "Details"). Groesse
und Farbe wie jede andere Nebenzeile. */
.row dd.row-hinweis { font-size: 12.5px; color: var(--fg3); }
.row-fussnote {
flex: 1 0 100%;
text-align: left;
@@ -632,11 +637,11 @@ button.leaf:active { background: var(--tile-2); }
260 px gestrichelte Leerfläche vor der Reichweite, der wichtigsten Zahl der
App. Mit Foto gilt wieder das volle Seitenverhältnis. */
.bildbox.bild-fehlt.carfix { aspect-ratio: auto; height: 132px; }
/* 72px statt 120px: ohne hinterlegtes Foto stand hier eine leere Flaeche
direkt ueber der Reichweite, der wichtigsten Zahl der Seite. Der
Platzhalter bleibt sichtbar - er ist der einzige Hinweis, dass es diesen
Bildplatz gibt - nur eben schmal (Designpruefung 2026-08-30). */
.bildbox.bild-fehlt.carfix.klein { height: 72px; }
/* Der Platzhalter belegt denselben Kasten wie ein echtes Foto (16:8). Er war
zwischenzeitlich auf 120 und dann 72px gestaucht, um die Reichweite
hoeher zu ruecken - auf Ansage des Besitzers steht er wieder in voller
Groesse, weil ein Streifen nicht erkennen laesst, was dort hingehoert. */
.bildbox.bild-fehlt.carfix.klein { aspect-ratio: 16 / 8; height: auto; }
.szene.bleed:has(.bild-fehlt)::before { display: none; }
.szene.bleed:has(.bild-fehlt) { margin-left: 0; margin-right: 0; }
.szene.bleed:has(.bild-fehlt) .carbox { padding: 0; }
@@ -1,7 +1,7 @@
{
"domain": "audi_dashboard",
"name": "Audi Dashboard",
"version": "2026.8.30.8",
"version": "2026.8.30.9",
"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"],