Logo-Pfad akzeptierte .heic, öffnete aber direkt mit Pillow (kein HEIF-Opener)
— iPhone-Fotos schlugen fehl. Jetzt convert_media-Vorstufe wie im Foto-Pfad.
Fehlgeschlagene Konvertierungen (HEIC→JPEG, MOV→MP4) brechen mit klarer
Meldung ab statt rohe Dateien zu speichern (MOV wäre als <img> kaputt gerendert).
Test: echter HEIC-Roundtrip (pillow-heif) für Logo + Foto.
Rene: 'Tagebuch Kalenderansicht/Karte nicht mehr da' — Root-Cause: 459cd42
ersetzte style="display:none" durch class="hidden", aber die Show-Pfade
setzten weiter style.display. .hidden hat !important und gewinnt immer
(gleiche Klasse wie Filter-Panel-Hotfix v1242). Prod-Logs bewiesen: kein
einziger /diary/calendar- oder /locations-Request kam je an.
Unsichtbar seit v1102, jetzt per classList gefixt:
- diary: Stats-Bar mit View-Switcher (Liste/Medien/Kalender/Karte) + Medien-Grid neuer Eintrag
- health: KI-Tierarzt-Ergebnis erschien nie
- walks: Challenge-/Stamm-Gassi-Tabs leer
- welcome: iOS-Panel der Desktop-Install-Anleitung
- wiki: Fotos-Mod-Badge + Foto-Fallback (via app.js data-fb show-el/sibling-Handler)
- routes: Filter-Badge; breeder: Fotos-Section
Zweite Fehlerklasse aus demselben Sprint: doppelte class-Attribute
(class="x" id=… class="hidden") — Browser verwirft das zweite Attribut.
87 Vorkommen in 23 Dateien zusammengeführt; betroffene Show/Hide-Pfade
(ev-map, rk-mine/nearby-group, chat-partner-dot, eh-panel, zh-section)
auf classList umgestellt.
Praxistest Rene (Gassirunde Siegenhofen, Loop Start=Ende): _closestIdx suchte
GLOBAL -> am Start war der END-Index genauso nah -> Fortschritt sprang ans
Track-Ende: nie Abbiege-Bellen (keine Turns mehr 'vor' einem), done-Linie
malte sofort alles gruen, 99%.
- _closestIdx: Fenster um den aktuellen Index (-15/+80), global nur beim
ersten Fix (mit Start-Praeferenz bei Quasi-Gleichstand <25m) oder wenn
verloren (>300m). Simulation auf der echten Route: 13/13 Turns feuern
bei 41-49m Vorlauf.
- Gelaufener Weg als BREADCRUMB: gruen = auf der Route, rot = daneben
(Segment-Wechsel nahtlos); done-Linie (Track-Slice-Malen) entfernt —
nie gelaufene Abschnitte bleiben jetzt orange
- Off-Route-Schwelle 50->35m (Klaeffen kam ~5m zu spaet), Abbiege-Ansage 45->50m
Bump v1250
- Standort-Punkt zeigt jetzt einen Kompass-KEGEL (wie Google Maps): CSS-Kegel
im loc-icon (GL + Leaflet), deviceorientation mit webkitCompassHeading (iOS)
bzw. 360-alpha (Android), Glaettung ueber kuerzesten Winkelweg, rAF-throttled.
iOS-Permission via User-Geste (Follow-/Standort-Button startet den Kompass).
- Follow pant nur noch bei brauchbarem Fix (accuracy < 75m) — ungenaue
Positionen liessen die Karte zappeln; GPS-Fixes frischer (maximumAge 2s
statt 5s). Marker aktualisiert weiterhin jeden Fix.
Bump v1249
Rene: aktiviertes Crosshair pannt alle paar Sekunden -> jedes moveend
startete den Scan. Scans aus KARTENBEWEGUNG laufen jetzt erst, wenn sich
das Zentrum >= 20% der Viewport-Breite bewegt hat oder der Zoom wechselt
(bei Z16 ~ alle 100-150m Fussweg). Alle anderen Trigger (Marker
gespeichert, Layer-Toggle, Retry, Init, Scan-Queue) ungebremst.
Bump v1247
position:fixed + safe-area (+70px) wie das Offline-Icon (+110px) statt
absolute im Karten-Container — sitzt jetzt exakt in der Luecke; Offline-
Puls bleibt unveraendert an seinem Platz.
Bump v1246
Wunsch Rene: sichtbarer Follow-Schalter direkt auf der Karte statt nur ueber
das Speed-Dial. Crosshair links unter den Zoom-Reglern (unterhalb des
Offline-Puls-Icons): Tipp = zentrieren + folgen (Button farbig), Karte
ziehen = pausiert (grau). Synchron mit Standort-Speed-Dial-Button und
Aufzeichnungs-Start (beide aktivieren Follow ebenfalls).
Bump v1245
HTMLAudio+preload laedt auf iOS lazy (canplaythrough feuert nie) und verlor
beim ersten Einschalten das Rennen gegen den Probe-Wuff -> Game-Boy-Fallback.
Jetzt: fetch + decodeAudioData in den bestehenden AudioContext (praezises
Timing via BufferSource, offline via SW-Precache); Probe-Wuff 450ms verzoegert.
Synthese bleibt Fallback bei 404/Decode-Fehler.
Bump v1244
Kaputt seit 27a3f95 (2026-06-05, 'Filter standardmaessig zu' setzte die
hidden-KLASSE ins Markup, der Toggle blieb aber auf style.display='').
.hidden = display:none !important (design-system.css) -> Klick wirkte nie.
Import funktionierte weiter (Label+File-Input nativ) — dadurch gemeldet
als 'Filter geht nicht mehr' (Angie + Rene).
Fix: classList.toggle('hidden') im Toggle + konsistent im Suggest-Tab.
Bump v1242
- NavSound (routes.js): WebAudio-Wuff-Synthese (Saegezahn-Sweep + Tiefpass,
kein Asset, laeuft offline); echte Aufnahmen unter /sounds/wuff.mp3 +
klaeffen.mp3 (z.B. von Yaro) werden automatisch bevorzugt
- Abbiege-Erkennung: Turns einmalig aus dem Track (Peilung ueber 15-m-
Stuetzpunkte gegen GPS-Zickzack, >=40 Grad), Ansage bei <=45 m davor,
einmal pro Abbiegepunkt
- Falscher Weg (>50 m, bestehende Warnung): Klaeffen beim Abkommen +
Erinnerung alle 30 s; zurueck auf Route reset
- Toggle im Navi-Header (Lautsprecher-Icon, by_nav_sound, Default AN),
iOS-Audio-Unlock beim Navi-Start + Toggle (Probe-Wuff als Bestaetigung)
Bump v1241
Vorher zaehlte NUR eine aufgezeichnete Tour der letzten 48h (<=50m am POI,
>=2 Punkte) — die aktuelle Geraeteposition floss gar nicht ein.
- DogFriendlyIn: optional user_lat/user_lon (Frontend schickt _userPos mit)
- Beleg-Weg a): Geraetestandort <= 75m am POI (50m Radius + GPS-Toleranz)
-> route_id=None markiert Live-Beleg; Weg b) Tour-Beleg unveraendert
- Fehlermeldung nennt jetzt beide Wege (hin gehen ODER Standort aktivieren)
- pytest 39 passed
Bump v1239
- MapGLMini-Polyline hatte KEIN addLatLng (nur setLatLngs) -> TypeError im
Rec-Overlay: Strecke unsichtbar, Marker fror ein, kein Folgen. Facade
ergaenzt (Leaflet-kompatibel).
- Rec-Overlay (routes.js): Follow-Mode default AN — Karte wandert mit dem
Standort, Drag pausiert, Crosshair-Button (unten rechts) reaktiviert;
erster Fix setzt Zoom 16, danach bleibt der Zoom erhalten
- Zentrale Karte (map.js): Standort-Button aktiviert Follow (+Toast),
dragstart beendet es (beide Engines); GPS-Tracking folgt sanft (easeTo);
Aufzeichnung startet im Follow-Mode, _updateRecMap pant nur noch im Follow
Bump v1238
Rene: Funkloecher + Routen waren nach 'Alles loeschen' weiter weg.
- Funkloch-Regionen jetzt im Keep-Set (geloescht wird NUR Manuelles);
Zonen behalten ihren Fuellstatus (Komplett-Wipe setzt weiter zurueck)
- Korridor-Migration beim Loeschen: keepTracks=[{name,track}] schreibt
Tracks in Alt-Eintraege ohne r.track (Bestand vor v1236) bzw. legt
fehlende Korridor-Regionen an — kein Warten auf Self-Healing
- clear() liefert Summary; Toast zeigt 'behalten: Standort, X Routen,
Y Funkloch-Gebiete' — Diagnose-Sichtbarkeit fuer Geraetetests
Bump v1237
Renes Befund: 'Alles loeschen' wischte weiter alles. Ursachen: (a) Bestands-
Gebiete hatten keine standort-Region (ensureHomeArea legt nur bei FEHLENDER
Kachel los), (b) Korridor-Keys waren nur aus API-Tracks ableitbar -> leeres
Keep-Set = Komplett-Wipe.
- downloadCorridor speichert vereinfachten Track (<=60 Pkt) in der Region-Meta;
clear() baut Korridor-Keep daraus — ohne API/Login/GPS
- Standort-ADOPTION: clear() mit center legt fehlende standort-Region
synthetisch an (Bestandsdaten vor Runde 6)
- map.js: center-Fallback auf by_last_position wenn GPS noch keinen Fix hat
- Test r7 erweitert (clear ohne Optionen haelt Korridor aus Meta), alle gruen
Bump v1236
Renes Modell Punkt 1 war zu eng interpretiert (nur Funkloecher): das Gebiet
um die aktuelle Position gehoert zur Grundversorgung.
- ensureHomeArea(lat,lon): Zentrums-Kachel-Check -> bei Luecke Budget-Download
(type 'standort', Cap-gated)
- Start-Check: Standort raw pruefen (ohne GL-Stack) und bei Bedarf laden
- 'Alles loeschen': Standort-Gebiet wird SOFORT neu geladen (+ Toast) —
vorher war die Offline-Funktionalitaet genau am wichtigsten Ort weg
- Pfote Segment 5: Standort-Kachel da UND Zonen im 50-km-Umkreis gefuellt
(ferne Zonen zaehlen nicht mehr — sie laden erst vor Ort)
- Tests r6 + Regression r1/r3/r4/r5 gruen
Bump v1234
Geraetetest: Karte offline 'nicht verfuegbar' obwohl Pfote ready zeigte —
activate loeschte die alten Static-Caches, waehrend der neue erst im
Hintergrund befuellt wurde; der GL-Stack (maplibre/pmtiles/map-offline)
war zudem nie im Precache, nur nach erster Online-Kartenoeffnung.
- activate: _migrateStaticCaches uebernimmt fehlende Eintraege der alten
Caches unter nacktem Key (Online-Refresh ueberschreibt sie sauber),
DANN erst loeschen
- PRIORITY_PAGES + GL-Karten-Stack (maplibre-gl.js/.css, pmtiles,
map-gl-style, map-offline, map-gl-markers, map-gl-mini)
- generischer Cache-First-Pfad: ignoreSearch-Fallback fuer eigene /js/+/css/
(?v=APP_VER zeigt sonst am Carry-Over/bare-Bestand vorbei)
Bump v1233
Bei schwachem Empfang blieb die App beim Start SEHR LANGE weiss: CSS +
Kern-JS + index.html waren Network-First OHNE Timeout — der Cache griff
nur bei hartem Fetch-Fehler, nicht bei troepfelnder Verbindung.
Jetzt: Promise.race(Netz, 2,5s) -> Cache-Fallback (stale-while-revalidate,
Netz aktualisiert den Cache im Hintergrund weiter). Versions-Updates laufen
weiter ueber x-app-version + controllerchange.
Bump v1232
- Indikator links unter die Zoom-Regler (rechts verdeckte Legenden-Chips)
- Flugmodus bei offener App -> Position raw als Funkloch-Zone (offline-Event)
- Ent-Funklochen: Zonen-Liste im Offline-Modal mit X (removeDeadZone)
- Warnungs-Aktualitaet: _mergeStore Bbox-Replace (aufgehobene Giftkoeder/
gefundene Hunde verschwinden; Fetch-Kreis deckt Bbox via sqrt2 ab;
fresh=null merged nie) + 24h-Refresh im 50km-Umkreis beim Start
- Routen offline nutzbar halten: ensureRouteCorridors beim Start-Check
(Stichproben-Verify, Re-Download aus preview_track, Region-Dedupe)
- Stub-Tests ins Repo: tests/js/ (r1/r3/r4/r5, alle gruen)
Bump v1231
Funkloch-Gedaechtnis = Quelle der Wahrheit, Kacheln = ableitbarer Cache:
- Ephemeres Vorausladen: Prefetch-Kacheln werden bei Aufzeichnungsende
geloescht, wenn die Runde kein Funkloch hatte (nur neue Keys)
- Netz-Probe bei Aufzeichnung (~2min, 6s-Timeout): erkennt Funkloecher auch
in bereits gespeicherten Gebieten (dort kein Remote-Miss als Signal)
- clear() behaelt Zonen (filled=false) -> naechster Online-Start laedt
Funkloch-Gebiete automatisch neu, auch nach 'Alles loeschen'
- Start-Check mit Position: nur Zonen im 50-km-Umkreis, naechste zuerst,
Coverage-Verify (faengt Eviction ab); Pfote Segment 5 = alle Zonen gefuellt
- Coverage-Layer zweifarbig: Funkloch orange, manuell blau + Modal-Legende
- Stub-Tests Runde 4 (Prune/Probe/clear/Naehe/Verify/Faerbung) bestanden
Bump v1230
Geraetetest-Befunde Runde 2:
- Giftkoeder verschwanden offline: /api/places kam aus dem SW-Cache (feste URL)
und verhinderte den allFailed-Fallback, waehrend /api/poison?lat=... (Bbox-URL)
scheiterte -> jetzt faellt jede Quelle EINZELN auf den letzten guten Stand
zurueck (localStorage) + Merge aus dem Offline-Region-Snapshot
- Region-Download speichert jetzt auch /api/poison + /api/lost der Gegend
(p/_poison, p/_lost, anonym; MapOffline.alerts(kind,bbox) als Reader) —
Sicherheitsdaten muessen auch am vorab gespeicherten Urlaubsort da sein
- lost.js Offline-Pfad merged den Region-Snapshot in Cache- und Leer-Fall
- Routen-Korridor war 'unsichtbar' (lag im schon gespeicherten Gebiet):
nach dem Speichern werden die gespeicherten Bereiche blau auf der
Detailkarte eingeblendet; Logik per Node-Stub-Test verifiziert
Bump v1227
Der SW beantwortet nicht-cachebare API-GETs offline mit 503 + JSON-Body,
r.json() wirft dann NICHT -> Erfolgs-Pfad ersetzte Marker durch {detail:...}.
_fetchPois prueft jetzt r.ok + Array.isArray, dadurch greift der
IndexedDB-Fallback (MapOffline.pois) in Phase 1 und Phase 2 behaelt den Bestand.
Bump v1224
- MapOffline.downloadAround speichert zusaetzlich /api/osm/pois je Typ fuer die
Region-Bbox in IndexedDB (Key-Praefix p/, Merge per id — zweite Region loescht
die erste nicht); MapOffline.pois(type,bbox) filtert fuer den Ausschnitt
- map.js Phase-1-Fallback: Fetch fehlgeschlagen (offline) -> gespeicherte
Region-POIs statt leerer Karte; Download-Toast zeigt Marker-Anzahl
- Offline-Banner: nach 5s auf schmale Icon-Leiste eingeklappt (verdeckte die
Karten-Legende); Inline-Styles nach components.css konsolidiert
- Bump v1223
- by_offline_tiles Default AN auf staging.banyaro.app (localStorage/?tilesoffline=1/0 uebersteuert)
- Speed-Dial 'Karte offline speichern': GL -> MapOffline.downloadAround(Kartenmitte, 5km),
Leaflet -> alter Raster-Prefetch (_cacheTiles war seit FAB-Redesign verwaist)
- Glyphs in IndexedDB (Key-Praefix f/) + byt://f/-Protokoll: ueberlebt App-Updates
- OSM-Raster-Prefetch im Offline-Tiles-Modus uebersprungen (GL nutzt das Raster nicht)
- Button-Sichtbarkeit gated: GL ohne Offline-Flag (= Production) zeigt ihn nicht
Der monatliche DSM-Job fragte nur germany/austria/switzerland ab, die Karte
deckt aber TILES_REGIONS (DACH + 12 Anrainer) ab -> POIs fehlten ausserhalb
DACH. Laenderliste jetzt in docker-compose.osm.yml als Env gesetzt (wirkt ohne
Image-Rebuild) und als Default in refresh.sh gespiegelt.
- app.js init(): Hash-Route wird auch ohne Login angesteuert — vorher wurden
anonyme Besucher IMMER auf 'welcome' geworfen, #agb/#datenschutz/#impressum
liefen damit ins Leere (DSGVO-Problem, broken Links aus iOS-App + SEO-Footer).
Auth-pflichtige Seiten schuetzt weiterhin der requiresAuth-Guard in navigate().
- main.py: /agb, /datenschutz, /impressum -> 302 auf die SPA-Hash-Routen
(vor dem SPA-Fallback registriert)
- make bump: v1221
MapLibre-GL-Migration ist verifiziert (Staging) → GL jetzt Default auf allen
deployten Hosts statt nur staging.banyaro.app. localhost/LAN bleibt OSM-Raster
(keine lokalen Tiles), by_map_gl=0 erzwingt weiterhin den Leaflet-Fallback.
Tiles (dach.pmtiles, 15 Länder) + Glyphs liegen nun auch im Prod-Data-Volume.
SW-Bump 1219→1220.
- Scrub-Bug: _radarPause() setzte slider.value zurück, BEVOR der gezogene Wert
gelesen wurde → sprang immer auf 'jetzt'. Jetzt Wert zuerst lesen. Scrubben
stoppt Play + zeigt den Frame der Position (verifiziert: Klick 20%→Frame 2,
Setter→5→Frame 5).
- Breite per JS an .map-statusbar angeglichen (gleiche linke + rechte Kante),
Höhe/Optik an die Pill (kleinerer Play-Button, flacher).