j/k nutzte ein starres 8px/16ms-setInterval (~500px/s, unsauber getaktet
gegenüber dem Frame-Takt) — ersetzt durch eine requestAnimationFrame-Schleife
mit sanftem Ramp-up (700 -> 1800px/s über 300ms), das behebt sowohl die zu
niedrige Geschwindigkeit als auch das Ruckeln kurz nach Scrollbeginn.
Der Service Worker war unter /static/js/sw.js registriert, wodurch sein
Scope (mangels Service-Worker-Allowed-Header) automatisch auf /static/js/
beschränkt war statt die ganze App abzudecken — Navigationen zu z.B. /
liefen nie durch den fetch-Handler, weshalb offline nur die Browser-eigene
Fehlerseite statt der App-Shell erschien. Jetzt wird sw.js zusätzlich unter
der Root /sw.js ausgeliefert (diora/urls.py) und dort mit explizitem
scope:'/' registriert; alte Registrierungen mit dem falschen Scope werden
beim Laden automatisch entfernt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Implement gPodder API v2 compatible endpoints at /api/2/:
- Auth: login/logout via HTTP Basic Auth or session
- Devices: list and register sync devices
- Subscriptions: get/add/remove per device, delta sync with ?since=
- Episode actions: upload play/position events, syncs to EpisodeProgress
- Server URL for AntennaPod: https://diora.creamfresh.xyz/api/2/
- Bump SW cache diora-v4 → v5 to force re-fetch of updated app.js
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>