Teilen-Blatt, HIG-Blaetter, geteilte Ansichtseinstellungen (2026.8.31.1)

Share-Erweiterung: ein PDF aus Mail landet ueber Teilen -> DataMetric360 als
Tankbeleg. Alles Native liegt versioniert unter companion-app/native/, weil
ios/ gitignored ist und npx cap add ios es sonst wieder frisst;
scripts/ios-teilen-einrichten.mjs haengt es bei jedem Bau ins Xcode-Projekt
und ist in ios-signieren.sh eingehaengt. Der pbxproj-Teil ist auf keinem Mac
erprobt - er bricht vor dem Schreiben ab, und docs/SHARE_EXTENSION.md
beschreibt dieselben Handgriffe fuer Xcode.

"In den Kalender uebernehmen" ging in der App nie: WKWebView ignoriert das
download-Attribut, der Klick lief ins Leere. Auf dem Geraet jetzt
@capacitor/filesystem plus @capacitor/share.

useTheme/useBoden legten je Aufrufer eigenen Zustand an - fuenf Kopien. Der
Schalter aenderte nur seine eigene, data-theme in App.tsx blieb stehen, die
Tag/Nacht-Umschaltung wirkte erst nach einem Neustart. Jetzt ein Speicher je
Einstellung ueber useSyncExternalStore. Zwei Regressionstests, gegen den
alten Stand als fehlschlagend nachgewiesen.

Alle Popups nach Apple HIG: neue Bausteine Sheet und ActionSheet, blickdicht
und mit abgedunkeltem Schleier, in beiden Codebasen. Popup portalierte nach
document.body - ausserhalb von [data-theme] - und war deshalb im Tagmodus
fast unsichtbar; Portal zielt jetzt auf .ads-root.

ImagePlaceholder merkte sich "fehlgeschlagen" ohne die Adresse: nach einem
leeren Galerieplatz zeigten auch die mit Foto nur noch den Platzhalter.
Vier Regressionstests, ebenfalls gegen den alten Stand geprueft.

Bildadressen tragen jetzt einen Cache-Brecher - HA liefert /local/ mit 31
Tagen Cache-Vorgabe aus, im Panel eingefuegte Radfotos erschienen in der App
deshalb nicht.

uebersichtsbild: Panel speichert den Namen, die App verglich gegen den
Dateinamen - der Vergleich traf nie zu. Kanonisch ist der Name.

Weiter: Navigationspfeil statt gleichschenkligem Dreieck auf der Streckenlinie
(die Kerbe unterscheidet Kopf und Ende), CI-Symbol tour-s als Fahrten-Icon,
Datumsfelder zeigen ihren Wert ohne erstes Antippen, feste Beispielnamen im
Setup, Kopf-Gegengewicht fuer mittige Titel, Standort-Blatt mit festem
Fussabstand, NSLocationWhenInUseUsageDescription, watchPosition fuer die
Live-Ortung, Art-Pille wieder als Knopf, Zwischenablage fuer Tankbelege.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-31 14:24:52 +02:00
parent 26f72930c3
commit b1411625aa
58 changed files with 2846 additions and 368 deletions
+27 -1
View File
@@ -63,6 +63,32 @@ export const ERLAUBTE_DATEINAMEN: readonly string[] = [
...WEITERE_BILDER,
]
/**
* Stand der Fahrzeugfotos, als Anhängsel an jede Bildadresse.
*
* Home Assistant liefert alles unter `/local/` mit
* `Cache-Control: public, max-age=2678400` aus — einunddreißig Tage
* (nachgemessen 2026-08-31). Ohne ein wechselndes Anhängsel zeigt die App
* deshalb einen Monat lang das Bild, das sie beim ersten Mal geholt hat:
* ein neu hochgeladenes Foto erscheint nicht, ein ersetztes bleibt das alte,
* und ein 404 von vorher bleibt ein 404. Genau das ist dem Eigentümer mit
* den Radfotos passiert — im Panel eingefügt, in der App unsichtbar.
*
* Das Panel hängt seit jeher `?v=${bildVersion}` an (`bildInfo()` dort) und
* setzt den Wert nach jedem Hochladen oder Löschen neu. Hier dasselbe: beim
* Start der App einmal, danach bei jeder Änderung.
*
* Der Preis ist ein erneuter Abruf je App-Start. Der ist gewollt — ein Foto,
* das der Nutzer nicht sieht, kostet mehr als ein Megabyte über eine
* Verbindung, die ohnehin gerade das ganze Fahrzeugprofil holt.
*/
let bildVersion = Date.now()
/** Nach dem Hochladen oder Löschen eines Fotos aufrufen. */
export function bildVersionErneuern(): void {
bildVersion = Date.now()
}
/**
* Adresse eines Fahrzeugfotos auf dem Server. Die Bilder liegen unter
* `/local/bilder/` — anders als beim alten Panel läuft die App nicht
@@ -72,7 +98,7 @@ export function bildUrl(dateiname: string | null | undefined): string | undefine
if (!dateiname) return undefined
const basis = zugangLesenSynchron()?.basisUrl
if (!basis) return undefined
return `${basis}/local/bilder/${dateiname}`
return `${basis}/local/bilder/${dateiname}?v=${bildVersion}`
}
/**