diff --git a/public/js/privacy-storage.js b/public/js/privacy-storage.js index 949199f..aacad36 100644 --- a/public/js/privacy-storage.js +++ b/public/js/privacy-storage.js @@ -85,10 +85,6 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {}; return nextValue; } - function cookiesEnabled() { - return false; - } - function routeId(route) { const id = route?.id ?? route?.routeId ?? route; if (id === null || id === undefined || id === '') return null; @@ -104,9 +100,25 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {}; return numericIdSet([...values, value]); } + function isRouteStateObject(value) { + return value && typeof value === 'object' && ( + Object.hasOwn(value, 'routeId') + || Object.hasOwn(value, 'routeState') + || Object.hasOwn(value, 'routeProgressIndex') + || Object.hasOwn(value, 'visitedPoiIds') + || Object.hasOwn(value, 'viewedPoiIds') + || Object.hasOwn(value, 'playedAudioPoiIds') + ); + } + function progressEnvelope(value) { - const routes = value?.routes && typeof value.routes === 'object' ? value.routes : value; - return routes && typeof routes === 'object' ? routes : {}; + if (!value || typeof value !== 'object') return {}; + if (value.routes && typeof value.routes === 'object') return value.routes; + if (isRouteStateObject(value)) { + const id = routeId(value); + return id ? { [id]: value } : {}; + } + return value; } function readProgressStore() { @@ -121,19 +133,27 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {}; }); } - function normalizeRouteState(value) { + function stateTimestamp(value) { + return Number(value?.updatedAt) || Number(value?.savedAt) || now(); + } + + function normalizeRouteState(value, fallbackRouteId = null) { if (!value || typeof value !== 'object') return null; + const id = value.routeId === null || value.routeId === undefined + ? fallbackRouteId + : value.routeId; + return { - routeId: value.routeId === null || value.routeId === undefined ? null : String(value.routeId), + routeId: id === null || id === undefined ? null : String(id), routeName: String(value.routeName ?? ''), routeState: value.routeState === 'running' || value.routeState === 'paused' ? value.routeState : 'idle', routeProgressIndex: Number.isInteger(value.routeProgressIndex) ? value.routeProgressIndex : null, visitedPoiIds: numericIdSet(value.visitedPoiIds), viewedPoiIds: numericIdSet(value.viewedPoiIds), playedAudioPoiIds: numericIdSet(value.playedAudioPoiIds), - savedAt: Number(value.savedAt) || Number(value.updatedAt) || 0, - updatedAt: Number(value.updatedAt) || Number(value.savedAt) || 0 + savedAt: Number(value.savedAt) || Number(value.updatedAt) || now(), + updatedAt: stateTimestamp(value) }; } @@ -153,13 +173,13 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {}; } function currentRouteState(routes, id, route = null) { - const normalized = normalizeRouteState(routes[id]); + const normalized = normalizeRouteState(routes[id], id); return normalized ?? freshEmptyRouteState(id, route); } function isExpired(value, referenceTime = now()) { - const timestamp = Number(value?.updatedAt) || Number(value?.savedAt) || 0; - return timestamp <= 0 || referenceTime - timestamp > MAX_PROGRESS_AGE_MS; + const timestamp = Number(value?.updatedAt) || Number(value?.savedAt) || now(); + return referenceTime - timestamp > MAX_PROGRESS_AGE_MS; } function reportCleanupProgress(callback, processed, total, removed) { @@ -179,7 +199,7 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {}; updated.routeId = id; updated.updatedAt = now(); if (!updated.savedAt) updated.savedAt = updated.updatedAt; - routes[id] = normalizeRouteState(updated); + routes[id] = normalizeRouteState(updated, id); return writeProgressStore(routes); } @@ -197,7 +217,7 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {}; })); } - function markPlayedAudio(route, poiId) { + function markAudioPlayed(route, poiId) { return updateRouteState(route, entry => ({ ...entry, playedAudioPoiIds: addNumericId(entry.playedAudioPoiIds, poiId) @@ -234,7 +254,7 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {}; let removed = 0; entries.forEach(([id, value], index) => { - const normalized = normalizeRouteState(value); + const normalized = normalizeRouteState(value, id); if (normalized && !isExpired(normalized, referenceTime)) kept[id] = normalized; else removed += 1; reportCleanupProgress(progressCallback, index + 1, entries.length, removed); @@ -255,7 +275,7 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {}; if (!id) return null; const routes = cleanupExpired().routes; - const saved = normalizeRouteState(routes[id]); + const saved = normalizeRouteState(routes[id], id); return saved && !isExpired(saved) ? saved : null; } @@ -267,11 +287,12 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {}; cleanExpiredProgress: cleanupExpiredProgress, cleanupExpired, cleanupExpiredProgress, - cookiesEnabled, + cookiesEnabled: () => false, getPrivacySettings: readSettings, isProgressStorageEnabled, - markPlayed: markPlayedAudio, - markPlayedAudio, + markAudioPlayed, + markPlayed: markAudioPlayed, + markPlayedAudio: markAudioPlayed, markVisited, markViewed, removeExpiredProgress: cleanupExpiredProgress,