diff --git a/backend/main.py b/backend/main.py index 7589a43..35fe0f8 100644 --- a/backend/main.py +++ b/backend/main.py @@ -341,7 +341,7 @@ MEDIA_DIR = os.getenv("MEDIA_DIR", "/data/media") os.makedirs(MEDIA_DIR, exist_ok=True) app.mount("/media", StaticFiles(directory=MEDIA_DIR), name="media") -APP_VER = "812" # muss mit APP_VER in app.js übereinstimmen +APP_VER = "813" # muss mit APP_VER in app.js übereinstimmen @app.get("/.well-known/assetlinks.json") async def assetlinks(): diff --git a/backend/static/index.html b/backend/static/index.html index bcd47de..6ccd78b 100644 --- a/backend/static/index.html +++ b/backend/static/index.html @@ -99,9 +99,9 @@ - - - + + + @@ -581,10 +581,10 @@ - - - - + + + + diff --git a/backend/static/js/api.js b/backend/static/js/api.js index c6203e7..893f1b4 100644 --- a/backend/static/js/api.js +++ b/backend/static/js/api.js @@ -49,8 +49,7 @@ const API = (() => { const serverVer = response.headers.get('x-app-version'); if (serverVer && serverVer !== APP_VER && !window._byUpdatePending) { window._byUpdatePending = true; - // App._showUpdateBanner wird aufgerufen sobald App initialisiert ist - setTimeout(() => window.App?._triggerUpdateBanner?.(serverVer), 0); + window._byNewVersion = serverVer; } if (response.status === 204) return null; diff --git a/backend/static/js/app.js b/backend/static/js/app.js index 00dad0c..d9a1c61 100644 --- a/backend/static/js/app.js +++ b/backend/static/js/app.js @@ -3,7 +3,7 @@ Router, State-Management, Navigation, Initialisierung. ============================================================ */ -const APP_VER = '812'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen +const APP_VER = '813'; // ← bei jedem Deploy mit Frontend-Änderungen erhöhen const APP_VERSION = '1.5.0'; // ← semantische Version, wird bei make release gesetzt const IS_STAGING = location.hostname === 'staging.banyaro.app'; // Cache-Bust-Parameter nach Update-Reload sofort entfernen @@ -119,6 +119,13 @@ const App = (() => { // ---------------------------------------------------------- function navigate(pageId, pushHistory = true, params = {}) { if (!pages[pageId]) return; + // Neue Version erkannt → jetzt sicher im Hintergrund aktualisieren + if (window._byUpdatePending) { + window._byUpdatePending = false; + sessionStorage.setItem('by_updated_to', window._byNewVersion || ''); + location.href = '/force-update'; + return; + } if (window.Worlds?._visible) window.Worlds.hide(); // Aktive Seite ausblenden @@ -885,6 +892,13 @@ const App = (() => { _bindNavigation(); + // Nach stillem Update: Toast anzeigen + const updatedTo = sessionStorage.getItem('by_updated_to'); + if (updatedTo) { + sessionStorage.removeItem('by_updated_to'); + setTimeout(() => UI.toast?.success(`App automatisch auf v${updatedTo} aktualisiert`), 1500); + } + try { localStorage.removeItem('by_wissen_open'); } catch (_) {} _initVersionCheck(); @@ -986,108 +1000,8 @@ const App = (() => { } // ---------------------------------------------------------- - // VERSION-CHECK - let _updateBannerShown = false; - - async function _checkVersion() { - try { - const r = await fetch('/api/version', { cache: 'no-store' }); - if (!r.ok) return; - const { version } = await r.json(); - if (version && version !== APP_VER && !_updateBannerShown) { - _updateBannerShown = true; - _showUpdateBanner(version); - } - } catch { /* offline — ignorieren */ } - } - - function _showUpdateBanner(newVersion) { - const isIos = /iphone|ipad|ipod/i.test(navigator.userAgent); - const existing = document.getElementById('app-update-banner'); - if (existing) return; - - const banner = document.createElement('div'); - banner.id = 'app-update-banner'; - banner.style.cssText = [ - 'position:fixed;bottom:calc(env(safe-area-inset-bottom,0px) + 72px);left:12px;right:12px', - 'z-index:9000;background:var(--c-primary);color:#fff;border-radius:16px', - 'padding:14px 16px;box-shadow:0 4px 20px rgba(0,0,0,0.3)', - 'display:flex;flex-direction:column;gap:10px', - ].join(';'); - - banner.innerHTML = ` -
-
-
- Neue Version verfügbar (v${newVersion}) -
-
- Tippe auf Aktualisieren um die neueste Version zu laden. -
-
-
- - -
-
- - `; - - document.body.appendChild(banner); - - banner.querySelector('#upd-btn-close').addEventListener('click', () => banner.remove()); - - banner.querySelector('#upd-btn-reload').addEventListener('click', () => { - location.href = '/force-update'; - }); - } - - function _initVersionCheck() { - // Beim Start nach 10 Sekunden prüfen (nicht sofort — Prio für Auth) - setTimeout(_checkVersion, 10_000); - // Dann alle 30 Minuten - setInterval(_checkVersion, 30 * 60_000); - // Beim Wiedereinstieg in die App - document.addEventListener('visibilitychange', () => { - if (document.visibilityState === 'visible') _checkVersion(); - }); - // Nach Reload: war das ein Update-Reload? Falls Version immer noch alt → iOS-Hinweis - const reloadVer = sessionStorage.getItem('by_update_reload'); - if (reloadVer && reloadVer === APP_VER) { - // Version hat sich nicht geändert nach Reload → iOS-Cache-Problem - sessionStorage.removeItem('by_update_reload'); - setTimeout(() => { - fetch('/api/version', { cache: 'no-store' }) - .then(r => r.json()) - .then(({ version }) => { - if (version && version !== APP_VER) { - _updateBannerShown = true; - _showUpdateBanner(version); - // iOS-Hinweis sofort aufklappen - setTimeout(() => { - document.getElementById('upd-ios-hint')?.style.setProperty('display', 'block'); - }, 300); - } - }).catch(() => {}); - }, 2000); - } - } + // VERSION-CHECK — stilles Auto-Update beim nächsten Seitenwechsel + function _initVersionCheck() { /* X-App-Version Header in api.js übernimmt das */ } // ---------------------------------------------------------- // ÖFFENTLICHE API @@ -1105,8 +1019,7 @@ const App = (() => { showOnboarding: _showOnboardingModal, updateNotifBadge: _updateNotifBadge, checkNearbyAlerts: _checkNearbyAlerts, - loadScript: _loadScript, - _triggerUpdateBanner: _showUpdateBanner }; + loadScript: _loadScript }; })(); diff --git a/backend/static/sw.js b/backend/static/sw.js index 50076b5..a37745c 100644 --- a/backend/static/sw.js +++ b/backend/static/sw.js @@ -3,7 +3,7 @@ Offline-Cache + Push Notifications + Tile-Cache ============================================================ */ -const CACHE_VERSION = 'by-v812'; +const CACHE_VERSION = 'by-v813'; const CACHE_STATIC = `${CACHE_VERSION}-static`; const CACHE_TILES = 'ban-yaro-tiles-v1'; // bleibt über SW-Updates erhalten const CACHE_API = 'ban-yaro-api-v1'; // API-Response-Cache