diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 534a3c4..6b43a9e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,8 +14,8 @@ android { applicationId = "no.naiv.tilfluktsrom" minSdk = 26 targetSdk = 35 - versionCode = 16 - versionName = "1.10.1" + versionCode = 17 + versionName = "1.10.2" // Deep link domain — single source of truth for manifest + Kotlin code val deepLinkDomain = "tilfluktsrom.naiv.no" diff --git a/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt b/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt index 9734c86..e6f130a 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/data/ShelterRepository.kt @@ -46,7 +46,7 @@ class ShelterRepository(private val context: Context) { .readTimeout(60, TimeUnit.SECONDS) .addInterceptor(Interceptor { chain -> chain.proceed(chain.request().newBuilder() - .header("User-Agent", "Tilfluktsrom/1.10.1") + .header("User-Agent", "Tilfluktsrom/1.10.2") .build()) }) .build() diff --git a/fastlane/metadata/android/en-US/changelogs/17.txt b/fastlane/metadata/android/en-US/changelogs/17.txt new file mode 100644 index 0000000..afb84a1 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/17.txt @@ -0,0 +1,2 @@ +- PWA-only release: share button is now visually consistent with the other status-bar icons, and updates apply automatically the next time you bring the app to the foreground (no manual reload needed) +- No Android changes diff --git a/fastlane/metadata/android/nb-NO/changelogs/17.txt b/fastlane/metadata/android/nb-NO/changelogs/17.txt new file mode 100644 index 0000000..6c1b216 --- /dev/null +++ b/fastlane/metadata/android/nb-NO/changelogs/17.txt @@ -0,0 +1,2 @@ +- PWA-utgivelse: del-knappen er visuelt konsistent med de andre ikonene i statuslinjen, og oppdateringer trer i kraft automatisk neste gang du henter appen i forgrunnen (ingen manuell omlasting) +- Ingen Android-endringer diff --git a/fastlane/metadata/android/nn-NO/changelogs/17.txt b/fastlane/metadata/android/nn-NO/changelogs/17.txt new file mode 100644 index 0000000..8f3c3ff --- /dev/null +++ b/fastlane/metadata/android/nn-NO/changelogs/17.txt @@ -0,0 +1,2 @@ +- PWA-utgjeving: del-knappen er visuelt jamn med dei andre ikona i statuslinja, og oppdateringar tek effekt automatisk neste gong du hentar appen i framgrunnen (inga manuell omlasting) +- Ingen Android-endringar diff --git a/pwa/index.html b/pwa/index.html index 2005b54..1a66208 100644 --- a/pwa/index.html +++ b/pwa/index.html @@ -25,7 +25,11 @@ diff --git a/pwa/src/main.ts b/pwa/src/main.ts index 6b1a920..8701c0f 100644 --- a/pwa/src/main.ts +++ b/pwa/src/main.ts @@ -11,12 +11,44 @@ import './styles/main.css'; import 'leaflet/dist/leaflet.css'; import { initLocale } from './i18n/i18n'; import { init } from './app'; -import { setStatus } from './ui/status-bar'; -import { t } from './i18n/i18n'; import { maybeShow as maybeShowIosInstallHint } from './ui/install-hint'; console.info(`[tilfluktsrom] build ${__BUILD_REVISION__}`); +// Make `registerType: 'autoUpdate'` actually auto-update the running tab. +// vite-plugin-pwa's autoUpdate strategy makes the new service worker +// skipWaiting + clientsClaim, but the JS already loaded in the open tab is +// the *old* build until something triggers a navigation. Without this +// listener, a deploy is invisible until the user manually refreshes. +// +// We *defer* the reload until the user next backgrounds the app +// (visibilityState === 'hidden') instead of reloading immediately. This is +// an emergency app: a mid-task reload would lose the selected shelter, +// compass mode, and any in-flight UI state right when the user can least +// afford to be surprised. Deferring keeps the "auto" promise (they're on +// the new version next time they look at the screen) without interrupting +// active use. +// +// The `wasAlreadyControlled` guard avoids reloading on the very first SW +// install (when there was no previous controller — that's a fresh visit, +// not an update). +if ('serviceWorker' in navigator) { + const wasAlreadyControlled = !!navigator.serviceWorker.controller; + let pendingReload = false; + + navigator.serviceWorker.addEventListener('controllerchange', () => { + if (!wasAlreadyControlled) return; + pendingReload = true; + }); + + document.addEventListener('visibilitychange', () => { + if (pendingReload && document.visibilityState === 'hidden') { + pendingReload = false; + window.location.reload(); + } + }); +} + document.addEventListener('DOMContentLoaded', async () => { initLocale(); @@ -25,14 +57,6 @@ document.addEventListener('DOMContentLoaded', async () => { await navigator.storage.persist(); } - // Listen for service worker updates — flash a status message when a new - // version activates so the user knows they have fresh code/data. - if ('serviceWorker' in navigator) { - navigator.serviceWorker.addEventListener('controllerchange', () => { - setStatus(t('update_success')); - }); - } - await init(); // Shown only on first iOS Safari visit, once per device. Placed after init() diff --git a/pwa/src/styles/main.css b/pwa/src/styles/main.css index 9e89200..f045d71 100644 --- a/pwa/src/styles/main.css +++ b/pwa/src/styles/main.css @@ -86,6 +86,13 @@ html, body { cursor: not-allowed; } +#share-btn svg { + display: block; + /* `↻` and `ℹ` glyphs sit on a baseline; an SVG inside an inline-flex + container can otherwise pick up extra descender space and look + misaligned next to them. `display:block` removes that. */ +} + /* --- Main content area (map or compass) --- */ #main-content { flex: 1;