diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ad7f5da..23b23f3 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 = 15 - versionName = "1.10.0" + versionCode = 14 + versionName = "1.9.1" // 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 5805368..a554375 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.0") + .header("User-Agent", "Tilfluktsrom/1.9.1") .build()) }) .build() diff --git a/pwa/index.html b/pwa/index.html index 8ce2047..7440b65 100644 --- a/pwa/index.html +++ b/pwa/index.html @@ -2,16 +2,9 @@ - - + - - - - Tilfluktsrom diff --git a/pwa/src/app.ts b/pwa/src/app.ts index 9e70099..ceceb58 100644 --- a/pwa/src/app.ts +++ b/pwa/src/app.ts @@ -101,14 +101,10 @@ function setupButtons(): void { const compassContainer = document.getElementById('compass-container')!; if (isCompassMode) { - // Request compass permission on first toggle (iOS requirement). - // On denial we stay in map mode and surface a status message so the - // user understands why nothing happened — silent reverting is the - // failure mode the Android GPS-denied banner was designed to avoid. + // Request compass permission on first toggle (iOS requirement) const granted = await compassProvider.requestPermission(); if (!granted) { isCompassMode = false; - statusBar.setStatus(t('compass_permission_denied')); return; } mapContainer.style.display = 'none'; diff --git a/pwa/src/i18n/en.ts b/pwa/src/i18n/en.ts index 8d585eb..6a77154 100644 --- a/pwa/src/i18n/en.ts +++ b/pwa/src/i18n/en.ts @@ -47,10 +47,6 @@ export const en: Record = { update_success: 'Shelter data updated', update_failed: 'Update failed \u2014 using cached data', error_shelter_not_found: 'Shelter not found', - compass_permission_denied: - 'Compass access denied. You can still use the map to find shelters.', - ios_install_hint: - 'Add Tilfluktsrom to your home screen for offline access: tap Share, then Add to Home Screen.', // Accessibility direction_arrow_description: 'Direction to shelter, %s away', diff --git a/pwa/src/i18n/nb.ts b/pwa/src/i18n/nb.ts index 2a00304..8c285d8 100644 --- a/pwa/src/i18n/nb.ts +++ b/pwa/src/i18n/nb.ts @@ -42,10 +42,6 @@ export const nb: Record = { update_success: 'Tilfluktsromdata oppdatert', update_failed: 'Oppdatering mislyktes — bruker lagrede data', error_shelter_not_found: 'Fant ikke tilfluktsrommet', - compass_permission_denied: - 'Kompasstilgang avslått. Du kan fortsatt bruke kartet til å finne tilfluktsrom.', - ios_install_hint: - 'Legg Tilfluktsrom til hjemskjermen for frakoblet bruk: trykk Del, deretter Legg til på hjem-skjerm.', // Tilgjengelighet direction_arrow_description: 'Retning til tilfluktsrom, %s unna', diff --git a/pwa/src/i18n/nn.ts b/pwa/src/i18n/nn.ts index 6e3fa8f..eace6bd 100644 --- a/pwa/src/i18n/nn.ts +++ b/pwa/src/i18n/nn.ts @@ -42,10 +42,6 @@ export const nn: Record = { update_success: 'Tilfluktsromdata oppdatert', update_failed: 'Oppdatering mislukkast — brukar lagra data', error_shelter_not_found: 'Fann ikkje tilfluktsrommet', - compass_permission_denied: - 'Kompasstilgang avslått. Du kan framleis bruke kartet til å finne tilfluktsrom.', - ios_install_hint: - 'Legg Tilfluktsrom til heimeskjermen for fråkopla bruk: trykk Del, deretter Legg til på heimeskjerm.', // Tilgjenge direction_arrow_description: 'Retning til tilfluktsrom, %s unna', diff --git a/pwa/src/main.ts b/pwa/src/main.ts index 6b1a920..003d83f 100644 --- a/pwa/src/main.ts +++ b/pwa/src/main.ts @@ -13,7 +13,6 @@ 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__}`); @@ -34,8 +33,4 @@ document.addEventListener('DOMContentLoaded', async () => { } await init(); - - // Shown only on first iOS Safari visit, once per device. Placed after init() - // so the banner doesn't compete with the loading overlay. - maybeShowIosInstallHint(); }); diff --git a/pwa/src/styles/main.css b/pwa/src/styles/main.css index 353dd0f..a7e2dfb 100644 --- a/pwa/src/styles/main.css +++ b/pwa/src/styles/main.css @@ -199,41 +199,6 @@ html, body { font-size: 12px; } -/* --- iOS "Add to Home Screen" hint (shown once, dismissable) --- */ -#ios-install-hint { - position: fixed; - left: 12px; - right: 12px; - bottom: 12px; - display: flex; - align-items: center; - gap: 8px; - padding: 10px 12px; - background: #16213E; - color: #ECEFF1; - border: 1px solid #FF6B35; - border-radius: 8px; - font-size: 13px; - line-height: 1.3; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4); - z-index: 1000; -} - -#ios-install-hint span { - flex: 1; -} - -#ios-install-hint button { - background: none; - border: 1px solid #ECEFF1; - color: #ECEFF1; - font-size: 12px; - padding: 4px 10px; - border-radius: 4px; - cursor: pointer; - flex-shrink: 0; -} - #cache-retry-btn { background: none; border: 1px solid #FFFFFF; diff --git a/pwa/src/ui/install-hint.ts b/pwa/src/ui/install-hint.ts deleted file mode 100644 index abc17f2..0000000 --- a/pwa/src/ui/install-hint.ts +++ /dev/null @@ -1,59 +0,0 @@ -/** - * iOS-only "Add to Home Screen" hint. - * - * Chrome-based browsers fire `beforeinstallprompt` and we could show a native - * install UI there; iOS Safari does not. For iOS users the only way to install - * is Share → Add to Home Screen, so we show a dismissable textual hint the - * first time they visit in a non-standalone context. - * - * Shown once per device (localStorage). Harmless if the heuristic mis-fires - * on a new iOS version — the hint is dismissable. - */ - -import { t } from '../i18n/i18n'; - -const DISMISSED_KEY = 'tilfluktsrom:ios-install-hint:dismissed'; - -function isIOS(): boolean { - // Safari on iPadOS 13+ reports as MacIntel, so also check for touch + Safari. - const ua = navigator.userAgent; - if (/iPad|iPhone|iPod/.test(ua)) return true; - return ( - navigator.maxTouchPoints > 1 && - /Macintosh/.test(ua) && - /Safari/.test(ua) && - !/Chrome|CriOS|FxiOS/.test(ua) - ); -} - -function isStandalone(): boolean { - // iOS-specific property - const nav = navigator as Navigator & { standalone?: boolean }; - if (nav.standalone) return true; - // Standards-based check used by Chrome/Edge - return window.matchMedia?.('(display-mode: standalone)').matches ?? false; -} - -export function maybeShow(): void { - if (!isIOS() || isStandalone()) return; - if (localStorage.getItem(DISMISSED_KEY) === '1') return; - - const banner = document.createElement('div'); - banner.id = 'ios-install-hint'; - banner.setAttribute('role', 'status'); - - const text = document.createElement('span'); - text.textContent = t('ios_install_hint'); - - const dismiss = document.createElement('button'); - dismiss.type = 'button'; - dismiss.textContent = t('action_close'); - dismiss.setAttribute('aria-label', t('action_close')); - dismiss.addEventListener('click', () => { - localStorage.setItem(DISMISSED_KEY, '1'); - banner.remove(); - }); - - banner.append(text, dismiss); - document.body.appendChild(banner); -}