Listenkoepfe vereinheitlicht, Zeilen mit Luft, Kalenderdateien mit Namen (2026.9.2.21-.23)
KOEPFE. Jahr und Monat tragen dasselbe Format (13px, Zweitfarbe, gemischt) - vorher drei Elemente in drei Formaten. Die Versalien aus .20 waren falsch: das ist der iOS-Stil vor 13. Vom Eigentuemer aus drei gerenderten Vorschlaegen gewaehlt. ZEILEN. padding-left 20px statt 0 - die Spalte des Aufklapp-Pfeils, damit die Zeilen auf derselben Kante stehen wie der Text der Koepfe. Nachgemessen bei 375px: Beschriftungsspalte 157px, laengster Ortsname 142,7px. GALERIE. Der gezeigte Platz ueberlebt den Seitenwechsel - er lag in der Komponente und starb mit ihr. Im Panel ist er seit jeher modulweit. KALENDER. Jeder Termin hiess "-.ics": in dateiname() fehlte das \w in der Zeichenklasse, es ueberlebten nur w/ae/oe/ue/ss und der Bindestrich. Zwei Termine ueberschrieben einander damit. Jetzt mit Umschrift und Rueckfall, und ueber Share.files statt Share.url. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -8284,3 +8284,57 @@ Projekts aus den Apple-Richtlinien.
|
||||
- **Hochladen über einen eigenen HTTP-Endpunkt** statt über den Dienst: hebt die 3-MB-Grenze des
|
||||
Panels auf (WebSocket, aiohttp-Vorgabe 4 MiB) und spart die Base64-Aufblähung. Gemessen: über
|
||||
REST gehen 12 MB durch, über den WebSocket bricht die Verbindung ab 3,2 MB Rohbild wortlos ab.
|
||||
|
||||
### Nachtrag .21-.23: gleiche Köpfe, Luft an den Zeilen, und `-.ics`
|
||||
|
||||
**Die Listenköpfe tragen jetzt dasselbe Format** (Vorschlag B von dreien, vom Eigentümer gewählt):
|
||||
Jahr und Monat beide 13px in der Zweitfarbe, gemischt geschrieben, ohne Sperrung; die Fahrtzeile
|
||||
bleibt 16px. Vorher standen drei Elemente in drei Formaten — 16px weiß, 11px grau gesperrt in
|
||||
Versalien, wieder 16px weiß. Die Versalien aus .20 waren mein Fehlgriff: sie sind der iOS-Stil vor
|
||||
13, heute schreibt Apple Abschnittsköpfe gemischt. Unterschieden werden die Ebenen über die
|
||||
Position, nicht über die Schrift. Tanken teilt die Regel; seine rechte Spalte bleibt bewusst
|
||||
anders (Ansage des Eigentümers).
|
||||
|
||||
Die drei Vorschläge lagen als gerendertes Muster vor (echte App-CSS, Audi Type, eigenständige HTML)
|
||||
— das ist der Weg, der bei Gestaltungsfragen zu einer Entscheidung führt, statt sie zu beschreiben.
|
||||
|
||||
**Die Zeilen haben wieder Luft**: `padding-left: 20px` statt 0. Das ist nicht geraten, sondern die
|
||||
Spalte des Aufklapp-Pfeils — die Zeilen stehen damit auf derselben Kante wie der Text der
|
||||
Kopfzeilen, wie iOS es in gruppierten Listen macht. Bei 375px behält die Beschriftungsspalte 157px,
|
||||
der längste Ortsname der Testdaten braucht 142,7px. Von den 58px aus .19 bleiben 38 gewonnen.
|
||||
|
||||
**Die Galerie merkt sich ihren Platz.** `useState(0)` setzte ihn bei jeder Rückkehr auf die
|
||||
Seitenansicht zurück. Im Panel war das nie aufgefallen, weil `bild` dort eine modulweite Variable
|
||||
ist und den Seitenwechsel überlebt; in der App lag der Zustand in der Komponente und starb mit ihr.
|
||||
|
||||
**Jeder Kalendertermin hieß `-.ics`.** In `dateiname()` stand `[^wäöüÄÖÜß-]`, gemeint war
|
||||
`[^\wäöüÄÖÜß-]` — ohne das `\w` überlebten nur w, ä, ö, ü, ß und der Bindestrich:
|
||||
|
||||
| Titel | vorher | jetzt |
|
||||
|---|---|---|
|
||||
| RS4 Avant competition: Ölwechsel | `-ö-w-.ics` | `rs4-avant-competition-oelwechsel.ics` |
|
||||
| Audi RS4: Inspektion | `-.ics` | `audi-rs4-inspektion.ics` |
|
||||
| Wechseltermin | `-.ics` | `wechseltermin.ics` |
|
||||
|
||||
Zwei verschiedene Termine überschrieben einander damit im Zwischenspeicher. Umlaute werden jetzt
|
||||
umgeschrieben statt weggeworfen (ein „ö" im Dateinamen muss über die Teilen-Kette prozentkodiert
|
||||
werden — eine Fehlerquelle weniger), und die Übergabe läuft über `files` statt `url`.
|
||||
|
||||
**Nicht bestätigt ist, dass das den Kalender-Export repariert.** Der Verdacht bleibt, dass iOS
|
||||
„Kalender" im Teilen-Blatt gar nicht als Ziel führt; der verlässliche Weg wäre EventKit, also
|
||||
nativ. Steht zur Prüfung beim Eigentümer.
|
||||
|
||||
### Was am 02.09. abends offen blieb
|
||||
|
||||
- **Fahrt bleibt offen, wenn das Trip-Signal ihr Ende nie meldet.** Im Testcontainer nachgewiesen:
|
||||
Trip-Status ging 16:33:15 auf `on` und nie wieder auf `off`, Zündung ging 16:54:21 aus, der
|
||||
Kilometerstand stand ab 16:52 (209.480 → 209.490, also 10 km). Im Laufzeitspeicher steht seither
|
||||
`fahrt_start_ts: 2026-09-02T16:32:18` — die Fahrt ist nie in der Liste gelandet. Der FMM003 hätte
|
||||
`trip=false` nach seinem eigenen 900-s-Timeout senden müssen. **Vorschlag, noch nicht gebaut**
|
||||
(der Eigentümer prüft zuerst den Dongle): bleibt das Trip-Signal an, während die Zündung länger
|
||||
als 900s + Puffer aus ist und der Kilometerstand steht, die Fahrt zum Zündungsende schließen.
|
||||
- **Zwischenablage:** `navigator.clipboard.read()` gibt in WebKit nur Text, HTML und Bilder heraus.
|
||||
Ein PDF ist dort nie zu holen — der Knopf kann nicht funktionieren. Entweder nativ über
|
||||
`UIPasteboard` oder er verschwindet auf dem Telefon.
|
||||
- **Teilen legt keinen Tankvorgang an** (Abschnitt BQ) — die drei OTA-Teile und der native Umbau
|
||||
stehen weiter aus.
|
||||
|
||||
@@ -33,9 +33,31 @@ interface AusstattungGruppe {
|
||||
serie?: string[]
|
||||
}
|
||||
|
||||
/** Zuletzt gezeigter Galerieplatz - modulweit, damit er den Seitenwechsel
|
||||
ueberlebt (siehe Begruendung in der Komponente). */
|
||||
let gemerkterBildIndex = 0
|
||||
|
||||
export function MeinAudi({ geheZu }: { geheZu: (name: SeitenName, id?: string) => void }) {
|
||||
const { fahrzeug, einstellungen } = useDaten()
|
||||
const [bildIndex, setzeBildIndex] = useState(0)
|
||||
/* Der Platz in der Galerie ueberlebt den Seitenwechsel.
|
||||
|
||||
useState(0) setzte ihn bei jeder Rueckkehr auf die Seitenansicht zurueck
|
||||
- wer sich das Cockpit ansah, im Menue wechselte und zurueckkam, fing
|
||||
wieder vorn an (gemeldet vom Eigentuemer, 02.09.2026). Im Panel ist das
|
||||
nie aufgefallen, weil `bild` dort eine modulweite Variable ist und den
|
||||
Seitenwechsel deshalb ueberlebt; hier liegt der Zustand in der
|
||||
Komponente und stirbt mit ihr.
|
||||
|
||||
Modulweit statt im Speicher: der Platz ist eine Ansichtssache, kein
|
||||
Datum. Er soll die Sitzung ueberleben, nicht den Neustart. */
|
||||
const [bildIndex, setzeBildIndexIntern] = useState(gemerkterBildIndex)
|
||||
const setzeBildIndex = (naechster: number | ((vorher: number) => number)) => {
|
||||
setzeBildIndexIntern((vorher) => {
|
||||
const wert = typeof naechster === "function" ? naechster(vorher) : naechster
|
||||
gemerkterBildIndex = wert
|
||||
return wert
|
||||
})
|
||||
}
|
||||
if (!fahrzeug || !einstellungen) return null
|
||||
|
||||
const aktiverSatz =
|
||||
|
||||
@@ -79,8 +79,29 @@ function hash(text: string): number {
|
||||
return wert
|
||||
}
|
||||
|
||||
/**
|
||||
* Dateiname für den Termin.
|
||||
*
|
||||
* Hier stand `[^wäöüÄÖÜß-]` - gemeint war `[^\\wäöüÄÖÜß-]`, also "alles
|
||||
* außer Wortzeichen". Ohne das `\\w` überlebten nur w, ä, ö, ü, ß und der
|
||||
* Bindestrich: aus "Wechseltermin" wurde `-.ics`, aus "Audi RS4: Inspektion"
|
||||
* ebenfalls `-.ics`. Ein Name ohne Stamm, und zwei verschiedene Termine
|
||||
* überschrieben einander im Zwischenspeicher.
|
||||
*
|
||||
* Jetzt mit Umlaut-Umschrift statt Wegwerfen (ein "ö" im Dateinamen muss über
|
||||
* die Teilen-Kette prozentkodiert werden und ist eine Fehlerquelle mehr),
|
||||
* zusammengefassten Bindestrichen und einem Rückfall, falls vom Titel nichts
|
||||
* übrig bleibt.
|
||||
*/
|
||||
function dateiname(titel: string): string {
|
||||
return `${titel.replace(/[^wäöüÄÖÜß-]+/g, "-").toLowerCase()}.ics`
|
||||
const stamm = titel
|
||||
.replace(/ä/g, "ae").replace(/ö/g, "oe").replace(/ü/g, "ue")
|
||||
.replace(/Ä/g, "Ae").replace(/Ö/g, "Oe").replace(/Ü/g, "Ue")
|
||||
.replace(/ß/g, "ss")
|
||||
.replace(/[^A-Za-z0-9]+/g, "-")
|
||||
.replace(/^-+|-+$/g, "")
|
||||
.toLowerCase()
|
||||
return `${stamm || "termin"}.ics`
|
||||
}
|
||||
|
||||
export async function kalenderDateiLaden(
|
||||
@@ -102,7 +123,10 @@ export async function kalenderDateiLaden(
|
||||
directory: Directory.Cache,
|
||||
encoding: Encoding.UTF8,
|
||||
})
|
||||
await Share.share({ title: titel, url: geschrieben.uri })
|
||||
/* files statt url: beides landet im Plugin als URL in den activityItems,
|
||||
aber `files` ist der dokumentierte Weg für lokale Dateien - `url` ist
|
||||
für Links gedacht. dialogTitle ist Android-only und schadet hier nicht. */
|
||||
await Share.share({ title: titel, files: [geschrieben.uri], dialogTitle: titel })
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -1092,27 +1092,39 @@ button.dm-sicherheitszeile:active { background: var(--tile-2); }
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
/* Der Monat ist ein Abschnittskopf, kein kleingeratener Eintrag.
|
||||
/* Jahr und Monat tragen DENSELBEN Kopf, die Fahrtzeile trägt den Inhalt.
|
||||
|
||||
Vorher unterschied er sich von der Fahrtzeile nur durch Größe (13 gegen
|
||||
16px) und Farbe - beim Lesen wirkte die Liste dadurch zweistufig statt
|
||||
dreistufig, und genau danach hat der Eigentümer gefragt (02.09.2026).
|
||||
Versalien plus Sperrung sind die Form, die iOS für Abschnittsköpfe
|
||||
benutzt und die in dieser Oberfläche schon über dem Seitentitel steht
|
||||
(.ads-eyebrow).
|
||||
In der Liste standen drei Elemente in drei Formaten: 2026 in 16px weiß,
|
||||
September in 11px grau gesperrt in Versalien, der Ortsname wieder in 16px
|
||||
weiß. Der Eigentümer hat das am 02.09.2026 als unprofessionell bezeichnet -
|
||||
zu Recht: zwei Köpfe, die dasselbe tun, sollen auch gleich aussehen.
|
||||
|
||||
11px und nicht 10: das ist die Untergrenze, die dieses Projekt aus den
|
||||
Apple-Richtlinien übernommen hat. In beiden Oberflächen dieselben Werte,
|
||||
damit der Kopf nicht je Gerät anders aussieht. */
|
||||
.dm-liste .ads-accordion--lvl2 .ads-acc-h__k {
|
||||
font-size: 11px;
|
||||
letter-spacing: .18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--fg3);
|
||||
Beide jetzt 13px in der Zweitfarbe, gemischt geschrieben und ohne Sperrung.
|
||||
Das ist zugleich die heutige Apple-Form: Abschnittsköpfe klein und in
|
||||
Sekundärfarbe, aber gemischt - Versalien sind der Stil vor iOS 13. Der
|
||||
Inhalt bleibt größer als sein Kopf, wie es die Richtlinien verlangen.
|
||||
Unterschieden werden die beiden Ebenen über die Position, nicht über die
|
||||
Schrift.
|
||||
|
||||
Von drei Vorschlägen (Monat als eigener Abschnitt ohne Aufklappen / beide
|
||||
Köpfe gleich / Jahr als Seitenüberschrift) hat der Eigentümer diesen
|
||||
gewählt: das Zusammenklappen ganzer Jahre bleibt erhalten. */
|
||||
.dm-liste .ads-acc-h__k {
|
||||
font-size: 13px;
|
||||
color: var(--fg2);
|
||||
}
|
||||
|
||||
/* 20px statt 0: die Zeilen standen sonst 34px vom Bildschirmrand entfernt und
|
||||
damit sichtbar enger als alles andere in der Kachel (gemeldet 02.09.2026).
|
||||
20px ist nicht geraten, sondern die Spalte des Aufklapp-Pfeils - die Zeilen
|
||||
stehen damit auf derselben Kante wie der Text der Kopfzeilen, so wie iOS es
|
||||
in gruppierten Listen macht.
|
||||
|
||||
Nachgemessen bei 375px: die Beschriftungsspalte behält 157px, der längste
|
||||
Ortsname der Testdaten ("Ingolstadt → Adelschlag") braucht 142,7px. Von den
|
||||
58px, die vorher verschenkt waren, bleiben 38 gewonnen. */
|
||||
.dm-liste .dm-blatt {
|
||||
padding-left: 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.dm-blatt {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":"2026.9.2.20","sha256":"04aa82b37c019eadf0c9c23bc27e4931b9371dba512ddd979adc1ea70f482924","bytes":266578,"gebaut":"2026-09-02T14:34:34Z"}
|
||||
{"version":"2026.9.2.23","sha256":"a4b55f9576980ea8f52a5c7782bc0879ff7e4c6561e19f844c44dad903bb87c5","bytes":266680,"gebaut":"2026-09-02T19:03:48Z"}
|
||||
Binary file not shown.
@@ -917,25 +917,38 @@ img.carfix.klein { aspect-ratio: auto; height: auto; }
|
||||
ohne Platz zu kosten. Beschränkt auf .liste, weil das linke Polster von
|
||||
.leaf anderswo (Batteriewerte, Servicebuch) gewollt ist. */
|
||||
.liste .lvl2 { margin-left: 0; }
|
||||
/* Der Monat ist ein Abschnittskopf, kein kleingeratener Eintrag.
|
||||
/* Jahr und Monat tragen DENSELBEN Kopf, die Fahrtzeile traegt den Inhalt.
|
||||
|
||||
Vorher unterschied er sich von der Fahrtzeile nur durch Groesse (13 gegen
|
||||
16px) und Farbe - beim Lesen wirkte die Liste dadurch zweistufig statt
|
||||
dreistufig, und genau danach hat der Eigentuemer gefragt (02.09.2026).
|
||||
Versalien plus Sperrung sind die Form, die iOS fuer Abschnittskoepfe
|
||||
benutzt und die in dieser Oberflaeche schon ueber dem Seitentitel steht
|
||||
(.eyebrow).
|
||||
In der Liste standen drei Elemente in drei Formaten: 2026 in 16px weiss,
|
||||
September in 11px grau gesperrt in Versalien, der Ortsname wieder in 16px
|
||||
weiss. Der Eigentuemer hat das am 02.09.2026 als unprofessionell
|
||||
bezeichnet - zu Recht: zwei Koepfe, die dasselbe tun, sollen auch gleich
|
||||
aussehen.
|
||||
|
||||
11px und nicht 10: das ist die Untergrenze, die dieses Projekt aus den
|
||||
Apple-Richtlinien uebernommen hat. In beiden Oberflaechen dieselben
|
||||
Werte, damit der Kopf nicht je Geraet anders aussieht. */
|
||||
.liste .lvl2 .acc-h .k {
|
||||
font-size: 11px;
|
||||
letter-spacing: .18em;
|
||||
text-transform: uppercase;
|
||||
color: var(--fg3);
|
||||
Beide jetzt 13px in der Zweitfarbe, gemischt geschrieben und ohne
|
||||
Sperrung. Das ist zugleich die heutige Apple-Form: Abschnittskoepfe
|
||||
klein und in Sekundaerfarbe, aber gemischt - Versalien sind der Stil vor
|
||||
iOS 13. Der Inhalt bleibt groesser als sein Kopf, wie es die Richtlinien
|
||||
verlangen. Unterschieden werden die beiden Ebenen ueber die Position,
|
||||
nicht ueber die Schrift.
|
||||
|
||||
Von drei Vorschlaegen (Monat als eigener Abschnitt ohne Aufklappen /
|
||||
beide Koepfe gleich / Jahr als Seitenueberschrift) hat der Eigentuemer
|
||||
diesen gewaehlt: das Zusammenklappen ganzer Jahre bleibt erhalten. */
|
||||
.liste .acc-h .k {
|
||||
font-size: 13px;
|
||||
color: var(--fg2);
|
||||
}
|
||||
.liste .leaf { padding-left: 0; }
|
||||
/* 20px statt 0: die Zeilen standen sonst 34px vom Bildschirmrand entfernt und
|
||||
damit sichtbar enger als alles andere in der Kachel (gemeldet 02.09.2026).
|
||||
20px ist nicht geraten, sondern die Spalte des Aufklapp-Pfeils - die
|
||||
Zeilen stehen damit auf derselben Kante wie der Text der Kopfzeilen, so
|
||||
wie iOS es in gruppierten Listen macht.
|
||||
|
||||
Nachgemessen bei 375px: die Beschriftungsspalte behaelt 157px, der
|
||||
laengste Ortsname der Testdaten ("Ingolstadt -> Adelschlag") braucht
|
||||
142,7px. Von den 58px, die vorher verschenkt waren, bleiben 38 gewonnen. */
|
||||
.liste .leaf { padding-left: 20px; }
|
||||
|
||||
.tile-h {
|
||||
display: block; width: 100%;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"domain": "audi_dashboard",
|
||||
"name": "Audi Dashboard",
|
||||
"version": "2026.9.2.20",
|
||||
"version": "2026.9.2.23",
|
||||
"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