Feature: Routenaufzeichnung übersteht App-Updates (Guard + Persistenz)

Stufe 1 (Guard): Während aktiver Aufzeichnung wird der SW-/Force-Update-Reload
aufgeschoben (window._byRecording → boot.js/_bySwReload + app.js force-update);
nach Stop/Speichern via window._byReloadIfPending() nachgeholt.

Stufe 2 (Persistenz): Track wird gedrosselt nach localStorage (RecStore) gesichert
und beim nächsten Öffnen der Karten-/Routen-Seite als 'Aufzeichnung fortsetzen?'
angeboten (Resume seedet Track+km+Startzeit). Schützt auch bei Crash/OS-Kill/
manuellem Reload. Greift in map.js UND routes.js. SW v1167
This commit is contained in:
rene 2026-06-04 17:13:23 +02:00
parent ddfb9474ef
commit 78866206b4
8 changed files with 174 additions and 40 deletions

View file

@ -46,6 +46,38 @@
_updateBanner();
})();
// ----------------------------------------------------------
// Aufzeichnungs-Speicher (Sicherheitsnetz gegen Datenverlust bei Reload/Crash)
// ----------------------------------------------------------
window.RecStore = {
save: function(s) { try { localStorage.setItem('by_active_recording', JSON.stringify(Object.assign({ ts: Date.now() }, s))); } catch (e) {} },
load: function() { try { return JSON.parse(localStorage.getItem('by_active_recording') || 'null'); } catch (e) { return null; } },
clear: function() { try { localStorage.removeItem('by_active_recording'); } catch (e) {} },
};
// ----------------------------------------------------------
// SW-Reload — wird während einer laufenden Routen-Aufzeichnung AUFGESCHOBEN,
// damit der nur im RAM gehaltene Track nicht verloren geht. Sobald die
// Aufzeichnung beendet ist, holt window._byReloadIfPending() den Reload nach.
// ----------------------------------------------------------
window._byReloadIfPending = function() {
if (window._byReloadPending) {
window._byReloadPending = false;
window.location.replace('/?_t=' + Date.now());
}
};
function _bySwReload() {
if (sessionStorage.getItem('by_skip_sw_reload')) {
sessionStorage.removeItem('by_skip_sw_reload'); // einmalig konsumieren
return;
}
if (window._byRecording) { // Aufzeichnung läuft → Reload aufschieben
window._byReloadPending = true;
return;
}
window.location.replace('/?_t=' + Date.now());
}
// ----------------------------------------------------------
// Service Worker Registration + Update-Flow
// ----------------------------------------------------------
@ -56,13 +88,7 @@ if ('serviceWorker' in navigator) {
function _watchSW(sw) {
if (!sw) return;
sw.addEventListener('statechange', function() {
if (sw.state === 'activated') {
if (sessionStorage.getItem('by_skip_sw_reload')) {
sessionStorage.removeItem('by_skip_sw_reload'); // einmalig konsumieren
return;
}
window.location.replace('/?_t=' + Date.now());
}
if (sw.state === 'activated') _bySwReload();
});
}
reg.addEventListener('updatefound', function() { _watchSW(reg.installing); });
@ -83,11 +109,7 @@ if ('serviceWorker' in navigator) {
// NICHT registrieren wenn diese Seite selbst durch SW-Reload entstand
if (!window._BY_SW_RELOAD) {
navigator.serviceWorker.addEventListener('controllerchange', function() {
if (sessionStorage.getItem('by_skip_sw_reload')) {
sessionStorage.removeItem('by_skip_sw_reload');
return;
}
window.location.replace('/?_t=' + Date.now());
_bySwReload();
});
}