diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md
deleted file mode 100644
index c544235..0000000
--- a/ARCHITECTURE.md
+++ /dev/null
@@ -1,455 +0,0 @@
-# Architecture
-
-This document describes the architecture of Tilfluktsrom, a Norwegian emergency shelter finder available as an Android app and a Progressive Web App (PWA). Both platforms share the same design philosophy — offline-first, no hard external dependencies — but are implemented independently.
-
-## Table of Contents
-
-- [Design Principles](#design-principles)
-- [Data Pipeline](#data-pipeline)
-- [Android App](#android-app)
- - [Package Structure](#package-structure)
- - [Data Layer](#data-layer)
- - [Location & Navigation](#location--navigation)
- - [Compass System](#compass-system)
- - [Map & Tile Caching](#map--tile-caching)
- - [Build Variants](#build-variants)
- - [Home Screen Widget](#home-screen-widget)
- - [Deep Linking](#deep-linking)
-- [Progressive Web App](#progressive-web-app)
- - [Module Structure](#module-structure)
- - [Build System](#build-system)
- - [Data Layer (PWA)](#data-layer-pwa)
- - [Location & Compass (PWA)](#location--compass-pwa)
- - [Map & Offline Tiles (PWA)](#map--offline-tiles-pwa)
- - [Service Worker](#service-worker)
- - [UI Components](#ui-components)
-- [Shared Algorithms](#shared-algorithms)
- - [UTM33N → WGS84 Conversion](#utm33n--wgs84-conversion)
- - [Haversine Distance & Bearing](#haversine-distance--bearing)
-- [Offline Capability Summary](#offline-capability-summary)
-- [Security & Privacy](#security--privacy)
-- [Internationalization](#internationalization)
-
----
-
-## Design Principles
-
-### Offline-First
-This is an emergency app. Core functionality — finding the nearest shelter, compass navigation, distance display — must work without internet after initial setup. Network is used only for initial data download, periodic refresh, and map tile caching.
-
-### De-Google Compatibility (Android)
-The Android app runs on devices without Google Play Services (LineageOS, GrapheneOS, /e/OS). Every Google-specific API has an AOSP fallback. Play Services improve accuracy and battery life when available, but are never required.
-
-### Minimal Dependencies
-Both platforms use few, well-chosen libraries. No heavy frameworks, no external CDNs at runtime. The PWA bundles everything locally; the Android app uses only OSMDroid, Room, OkHttp, and WorkManager.
-
-### Data Sovereignty
-Shelter data comes directly from Geonorge (the Norwegian mapping authority). No intermediate servers. The app fetches, converts, and caches the data locally.
-
----
-
-## Data Pipeline
-
-Both platforms consume the same upstream data source:
-
-```
-Geonorge ZIP (EPSG:25833 UTM33N)
- ↓ Download (~320KB)
- ↓ Extract GeoJSON from ZIP
- ↓ Parse features
- ↓ Convert UTM33N → WGS84 (Karney method)
- ↓ Validate (Norway bounding box, required fields)
- ↓ Store locally
-```
-
-**Source URL:** `https://nedlasting.geonorge.no/geonorge/Samfunnssikkerhet/TilfluktsromOffentlige/GeoJSON/Samfunnssikkerhet_0000_Norge_25833_TilfluktsromOffentlige_GeoJSON.zip`
-
-**Fields per shelter:**
-
-| Field | Description |
-|------------|--------------------------------------|
-| `lokalId` | Unique identifier (UUID) |
-| `romnr` | Shelter room number |
-| `plasser` | Capacity (number of people) |
-| `adresse` | Street address |
-| `latitude` | WGS84 latitude (converted from UTM) |
-| `longitude`| WGS84 longitude (converted from UTM) |
-
-**When conversion happens:**
-- **Android:** At runtime during data download (`ShelterGeoJsonParser`)
-- **PWA:** At build time (`scripts/fetch-shelters.ts`), output is pre-converted `shelters.json`
-
----
-
-## Android App
-
-**Language:** Kotlin · **Min SDK:** 26 (Android 8.0) · **Target SDK:** 35
-**Build:** Gradle 8.7, AGP 8.5.2, KSP for Room annotation processing
-
-### Package Structure
-
-```
-no.naiv.tilfluktsrom/
-├── TilfluktsromApp.kt # Application class (OSMDroid config)
-├── MainActivity.kt # Central UI controller (~870 lines)
-├── data/
-│ ├── Shelter.kt # Room entity
-│ ├── ShelterDatabase.kt # Room database singleton
-│ ├── ShelterDao.kt # Data access object (Flow queries)
-│ ├── ShelterRepository.kt # Repository: bundled seed + network refresh
-│ ├── ShelterGeoJsonParser.kt # GeoJSON ZIP → Shelter list
-│ └── MapCacheManager.kt # Offline map tile pre-caching
-├── location/
-│ ├── LocationProvider.kt # GPS provider (flavor-specific)
-│ └── ShelterFinder.kt # Nearest N shelters by Haversine
-├── ui/
-│ ├── DirectionArrowView.kt # Custom compass arrow View
-│ ├── ShelterListAdapter.kt # RecyclerView adapter for shelter list
-│ ├── CivilDefenseInfoDialog.kt # Emergency instructions
-│ └── AboutDialog.kt # Privacy and copyright
-├── util/
-│ ├── CoordinateConverter.kt # UTM33N → WGS84 (Karney method)
-│ └── DistanceUtils.kt # Haversine distance and bearing
-└── widget/
- ├── ShelterWidgetProvider.kt # Home screen widget (flavor-specific)
- └── WidgetUpdateWorker.kt # WorkManager periodic update
-```
-
-Files under `location/` and `widget/` have separate implementations per build variant:
-- `app/src/standard/java/` — Google Play Services variant
-- `app/src/fdroid/java/` — AOSP-only variant
-
-### Data Layer
-
-**Storage:** Room (SQLite) with a single `shelters` table.
-
-**Loading strategy (three-layer fallback):**
-
-1. **Bundled asset** (`assets/shelters.json`): Pre-converted WGS84 data, loaded on first launch via `ShelterRepository.seedFromAsset()`. Marked as stale (timestamp=0) so a network refresh is attempted when possible.
-
-2. **Room database**: ~556 shelters cached locally. Reactive updates via Kotlin Flow. Atomic refresh: `deleteAll()` + `insertAll()` in a single transaction.
-
-3. **Network refresh**: Downloads the Geonorge ZIP via OkHttp, parses with `ShelterGeoJsonParser`. Staleness threshold: 7 days. Runs in the background; failure does not block the UI.
-
-**GeoJSON parsing pipeline:**
-```
-OkHttp response stream
- → ZipInputStream (find .geojson entry, 10MB size limit)
- → JSON parsing (features array)
- → Per feature:
- → Extract UTM33N coordinates
- → CoordinateConverter.utm33nToWgs84()
- → Validate: lokalId not blank, plasser ≥ 0, within Norway bounds
- → Create Shelter entity (skip malformed features with warning)
-```
-
-### Location & Navigation
-
-**LocationProvider** abstracts GPS access with two flavor implementations:
-
-| Flavor | Primary | Fallback |
-|-----------|----------------------------------|-------------------|
-| standard | FusedLocationProviderClient | LocationManager |
-| fdroid | LocationManager | — |
-
-Both emit location updates via Kotlin Flow. Update interval: 5 seconds, fastest 2 seconds.
-
-**ShelterFinder** takes the user's position and all shelters, computes Haversine distance and initial bearing for each, sorts by distance, and returns the N nearest (default: 3) as `ShelterWithDistance` objects.
-
-### Compass System
-
-**Sensor priority:**
-1. Rotation Vector sensor (`TYPE_ROTATION_VECTOR`) — most accurate, single sensor
-2. Accelerometer + Magnetometer — low-pass filtered (α=0.25) for smoothing
-3. No compass available — error message shown
-
-**Direction calculation:**
-```
-arrowAngle = shelterBearing − deviceHeading
-```
-
-**DirectionArrowView** is a custom View that draws:
-- A large arrow rotated by `arrowAngle`, pointing toward the shelter
-- An optional north indicator on the perimeter for compass calibration
-
-### Map & Tile Caching
-
-**Map library:** OSMDroid (OpenStreetMap, no Google dependency).
-
-**Tile caching:** OSMDroid's built-in `SqlTileWriter` passively caches every tile loaded. `MapCacheManager` supplements this with active pre-caching:
-
-- Pans the MapView across a 3×3 grid at zoom levels 10, 12, 14, 16
-- 300ms delay between pans (respects OSM tile usage policy)
-- Covers ~15km radius around the user
-- Progress reported via callback for UI display
-
-Tile cache stored in app-specific internal storage (`osmdroidBasePath`).
-
-### Build Variants
-
-```
-productFlavors {
- standard { } // Google Play Services + AOSP fallback
- fdroid { } // AOSP only
-}
-```
-
-The `standard` flavor adds `com.google.android.gms:play-services-location`. Runtime detection via `GoogleApiAvailability` determines which code path runs.
-
-Both flavors produce identical user experiences — `standard` achieves faster GPS fixes and better battery efficiency when Play Services are present.
-
-### Home Screen Widget
-
-**ShelterWidgetProvider** displays the nearest shelter's address, capacity, and distance. Updated by:
-
-1. **MainActivity** — sends latest location on each GPS update
-2. **WorkManager** — `WidgetUpdateWorker` runs every 15 minutes, requests a fresh location fix
-3. **Manual** — user taps refresh button on the widget
-
-**Location resolution (priority order):**
-1. Location from intent (WorkManager or MainActivity)
-2. FusedLocationProviderClient cache (standard)
-3. Active GPS request (10s timeout)
-4. LocationManager cache
-5. SharedPreferences saved location (max 24h old)
-
-### Deep Linking
-
-**HTTPS App Links:** `https://tilfluktsrom.naiv.no/shelter/{lokalId}`
-
-The domain is configured in one place: `DEEP_LINK_DOMAIN` in `build.gradle.kts` (exposed as `BuildConfig.DEEP_LINK_DOMAIN` and manifest placeholder `${deepLinkHost}`).
-
-- `autoVerify="true"` on the HTTPS intent filter triggers Android's App Links verification at install time
-- Verification requires `/.well-known/assetlinks.json` to be served by the PWA (in `pwa/public/.well-known/`)
-- If the app is installed and verified, `/shelter/*` links open the app directly (no disambiguation dialog)
-- If not installed, the link opens in the browser, where the PWA handles it
-
-Share messages include the HTTPS URL, which SMS apps auto-link as a tappable URL.
-
----
-
-## Progressive Web App
-
-**Stack:** TypeScript, Vite 5, Leaflet, idb (IndexedDB wrapper), vite-plugin-pwa
-**Package manager:** bun
-
-### Module Structure
-
-```
-pwa/
-├── index.html # SPA shell, CSP headers, semantic layout
-├── vite.config.ts # Build config, PWA plugin, tile caching rules
-├── manifest.webmanifest # PWA metadata and icons
-├── scripts/
-│ └── fetch-shelters.ts # Build-time: download + convert shelter data
-├── public/
-│ └── data/shelters.json # Pre-processed shelter data (build artifact)
-└── src/
- ├── main.ts # Entry point, SW registration, locale init
- ├── app.ts # Main controller (~400 lines)
- ├── types.ts # Shelter, ShelterWithDistance, LatLon interfaces
- ├── data/
- │ ├── shelter-repository.ts # Fetch + IndexedDB storage
- │ └── shelter-db.ts # IndexedDB wrapper (idb library)
- ├── location/
- │ ├── location-provider.ts # navigator.geolocation wrapper
- │ ├── compass-provider.ts # DeviceOrientationEvent (iOS/Android)
- │ └── shelter-finder.ts # Haversine nearest-N calculation
- ├── ui/
- │ ├── map-view.ts # Leaflet map, custom SVG markers
- │ ├── compass-view.ts # Canvas-based direction arrow
- │ ├── shelter-list.ts # Bottom sheet shelter list
- │ ├── loading-overlay.ts # Modal spinner / cache prompt
- │ ├── about-dialog.ts # Privacy, data info, cache clear
- │ ├── civil-defense-dialog.ts # DSB 5-step emergency guide
- │ └── status-bar.ts # Status text and refresh button
- ├── cache/
- │ └── map-cache-manager.ts # Tile pre-caching via programmatic panning
- ├── i18n/
- │ ├── i18n.ts # Locale detection, string substitution
- │ ├── en.ts # English strings
- │ ├── nb.ts # Bokmål strings
- │ └── nn.ts # Nynorsk strings
- ├── util/
- │ └── distance-utils.ts # Haversine distance, bearing, formatting
- └── main.css # Dark theme, Leaflet overrides, dialogs
-```
-
-### Build System
-
-**Vite** bundles the app with content-hashed filenames for cache busting.
-
-**Key configuration:**
-- Base path: `./` (relative, deployable anywhere)
-- `__BUILD_REVISION__` define: ISO timestamp injected at build time, used to invalidate service worker caches
-- **vite-plugin-pwa**: Generates the service worker with Workbox. Precaches all static assets. Runtime-caches OSM tile requests with CacheFirst strategy (30-day expiry, max 5000 entries).
-
-**Build-time data preprocessing:**
-`scripts/fetch-shelters.ts` downloads the Geonorge ZIP, extracts the GeoJSON, converts UTM33N→WGS84, validates, and writes `public/data/shelters.json`. This means coordinate conversion is a build step, not a runtime cost.
-
-```bash
-bun run fetch-shelters # Download and convert shelter data
-bun run build # TypeScript check + Vite build + SW generation
-```
-
-### Data Layer (PWA)
-
-**Storage:** IndexedDB via the `idb` library.
-
-**Schema:**
-- Object store `shelters` (keyPath: `lokalId`) — full shelter records
-- Object store `metadata` — `lastUpdate` timestamp
-
-**Loading strategy:**
-1. Check IndexedDB for cached shelters
-2. If empty or stale (>7 days): fetch `shelters.json` (precached by service worker)
-3. Replace all records in a single transaction
-4. Reactive: UI reads from IndexedDB after load
-
-Unlike the Android app, the PWA does not perform coordinate conversion at runtime — `shelters.json` is pre-converted at build time and served as a static asset.
-
-### Location & Compass (PWA)
-
-**Location:** `navigator.geolocation.watchPosition()` with high accuracy enabled, 10s maximum age, 30s timeout.
-
-**Compass:** DeviceOrientationEvent with platform-specific handling:
-
-| Platform | API | Heading Source |
-|----------------|------------------------------|--------------------------|
-| iOS Safari | `deviceorientation` | `webkitCompassHeading` |
-| Android Chrome | `deviceorientationabsolute` | `(360 − alpha) % 360` |
-
-iOS 13+ requires an explicit permission request (`DeviceOrientationEvent.requestPermission()`), triggered by a user gesture.
-
-Low-pass filter (smoothing factor 0.3) with 0/360° wraparound handling ensures fluid rotation.
-
-### Map & Offline Tiles (PWA)
-
-**Map library:** Leaflet with OpenStreetMap tiles. No CDN — Leaflet is bundled from `node_modules`.
-
-**Custom markers:** SVG-based `divIcon` elements — orange house with "T" for shelters, blue circle for user location. Selected shelter uses a larger yellow marker.
-
-**Auto-fit logic:** When a shelter is selected, the map fits bounds to show both user and shelter (30% padding), unless the user has manually panned or zoomed. A "reset view" button appears after manual interaction.
-
-**Tile pre-caching:** `MapCacheManager` uses the same approach as the Android app — programmatically pans the map across a 3×3 grid at 4 zoom levels. The service worker's runtime cache intercepts and stores the tile requests. Cache location stored in localStorage (rounded to ~11km precision for privacy).
-
-### Service Worker
-
-Generated by vite-plugin-pwa (Workbox):
-
-- **Precaching:** All static assets (JS, CSS, HTML, JSON, images) with content-hash versioning
-- **Runtime caching:** OSM tiles from `{a,b,c}.tile.openstreetmap.org` with CacheFirst strategy, 30-day TTL, max 5000 entries
-- **Navigation fallback:** Serves `index.html` for all navigation requests (SPA behavior)
-- **Auto-update:** New service worker activates automatically; `controllerchange` event notifies the user
-
-`main.ts` injects the build revision into the service worker context, ensuring each build invalidates stale caches. It also requests persistent storage (`navigator.storage.persist()`) to prevent the browser from evicting cached data.
-
-### UI Components
-
-The PWA uses no framework — all UI is vanilla TypeScript manipulating the DOM.
-
-| Component | Description |
-|--------------------------|----------------------------------------------------------|
-| `app.ts` | Main controller: wires components, manages state |
-| `map-view.ts` | Leaflet map with custom markers, auto-fit, interaction tracking |
-| `compass-view.ts` | Canvas-rendered arrow with north indicator, requestAnimationFrame |
-| `shelter-list.ts` | Bottom sheet with 3 nearest shelters, click selection |
-| `loading-overlay.ts` | Modal: spinner during load, OK/Skip for cache prompt |
-| `about-dialog.ts` | Privacy statement, data sources, "clear cache" button |
-| `civil-defense-dialog.ts`| DSB emergency instructions (5 steps) |
-| `status-bar.ts` | Data freshness indicator, refresh button |
-
-Dialogs are created dynamically and implement focus management (save/restore previous focus, trap focus inside modal).
-
----
-
-## Shared Algorithms
-
-Both platforms implement these algorithms independently (no shared code), ensuring each platform has zero runtime dependencies on the other.
-
-### UTM33N → WGS84 Conversion
-
-**Algorithm:** Karney series expansion method.
-
-Converts EUREF89 / UTM zone 33N (EPSG:25833) to WGS84 (EPSG:4326).
-
-**Constants:**
-- Semi-major axis: 6,378,137 m
-- Flattening: 1/298.257223563
-- UTM zone 33 central meridian: 15° E
-- Scale factor: 0.9996
-- False easting: 500,000 m
-
-**Steps:**
-1. Remove false easting/northing
-2. Compute footprint latitude using series expansion
-3. Apply iterative corrections for latitude and longitude
-4. Add central meridian offset
-
-**Validation:** Reject results outside Norway bounding box (57–72°N, 3–33°E).
-
-**Implementations:**
-- Android: `util/CoordinateConverter.kt` (runtime)
-- PWA: `scripts/fetch-shelters.ts` (build-time)
-
-### Haversine Distance & Bearing
-
-**Distance** between two WGS84 points:
-```
-a = sin²(Δφ/2) + cos(φ₁) · cos(φ₂) · sin²(Δλ/2)
-d = 2R · atan2(√a, √(1−a))
-```
-Where R = 6,371 km (Earth mean radius).
-
-**Initial bearing** from point 1 to point 2:
-```
-θ = atan2(sin(Δλ) · cos(φ₂), cos(φ₁) · sin(φ₂) − sin(φ₁) · cos(φ₂) · cos(Δλ))
-```
-Result in degrees: 0° = north, 90° = east, 180° = south, 270° = west.
-
-**Implementations:**
-- Android: `util/DistanceUtils.kt`
-- PWA: `util/distance-utils.ts`
-
----
-
-## Offline Capability Summary
-
-| Capability | Android | PWA |
-|-------------------------|----------------------------------|------------------------------------|
-| Shelter data | Room DB + bundled asset seed | IndexedDB + precached JSON |
-| Map tiles | OSMDroid SqlTileWriter + active pre-cache | Service worker CacheFirst + active pre-cache |
-| GPS | Device hardware (no network) | Device hardware (no network) |
-| Compass | Device sensors | DeviceOrientationEvent |
-| Distance/bearing math | Local computation | Local computation |
-| Network required for | Initial refresh, new tiles | Initial page load, new tiles |
-| Staleness threshold | 7 days | 7 days |
-
----
-
-## Security & Privacy
-
-- **No tracking:** No analytics, no telemetry, no external requests beyond Geonorge data and OSM tiles
-- **No user accounts:** No registration, no login, no server-side storage
-- **Location stays local:** GPS coordinates are used only for distance calculation and never transmitted
-- **HTTPS enforced:** Android network security config restricts to TLS; PWA CSP headers restrict connections
-- **ZIP bomb protection:** 10MB limit on uncompressed GeoJSON (Android parser)
-- **CSP headers (PWA):** Restrictive Content-Security-Policy blocks external scripts; `img-src` allows only OSM tile servers
-- **Input validation:** Shelter data validated at parse time (bounds check, required fields, non-negative capacity)
-- **Minimal permissions:** Location only; no contacts, camera, storage (except legacy tile cache on Android ≤9)
-
----
-
-## Internationalization
-
-Both platforms support three languages:
-
-| Language | Android | PWA |
-|---------------------|----------------------|----------------|
-| English (default) | `values/strings.xml` | `i18n/en.ts` |
-| Norwegian Bokmål | `values-nb/strings.xml` | `i18n/nb.ts` |
-| Norwegian Nynorsk | `values-nn/strings.xml` | `i18n/nn.ts` |
-
-**Android:** Uses Android's built-in locale resolution. Per-app language selection supported on Android 13+ via `locales_config.xml`.
-
-**PWA:** Detects browser language (`navigator.language`). String substitution supports `%d` (number) and `%s` (string) placeholders. Falls back to English for unsupported locales.
diff --git a/CLAUDE.md b/CLAUDE.md
index df4f859..a5b4d4d 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -58,26 +58,10 @@ no.naiv.tilfluktsrom/
- **fdroid**: AOSP-only, no Google dependencies
## Distribution
-- **Forgejo** (primary): `kode.naiv.no/olemd/tilfluktsrom` — releases with both APK variants + PWA tarball
+- **Forgejo** (primary): `kode.naiv.no/olemd/tilfluktsrom` — releases with both APK variants
- **GitHub** (mirror): `github.com/olemd/tilfluktsrom` — automatically mirrored from Forgejo, do not push manually
- **F-Droid**: Metadata maintained in a separate fdroiddata repo (GitLab fork). F-Droid builds from source using the `fdroid` variant and signs with the F-Droid key.
-## Release Process
-When creating a new release:
-1. Bump `versionCode` and `versionName` in `app/build.gradle.kts`
-2. Update User-Agent string in `ShelterRepository.kt` to match new version
-3. Build Android APKs: `./gradlew assembleStandardRelease assembleFdroidRelease`
-4. Build PWA: `cd pwa && bun scripts/fetch-shelters.ts && bun run build && tar -czf /tmp/tilfluktsrom-vX.Y.Z-pwa.tar.gz -C dist .`
-5. Commit, push, then create Forgejo release with all three artifacts:
- ```bash
- fj release create --create-tag vX.Y.Z --branch main \
- --attach "/tmp/tilfluktsrom-vX.Y.Z-standard.apk:tilfluktsrom-vX.Y.Z-standard.apk" \
- --attach "/tmp/tilfluktsrom-vX.Y.Z-fdroid.apk:tilfluktsrom-vX.Y.Z-fdroid.apk" \
- --body "release notes" "vX.Y.Z"
- fj release asset create vX.Y.Z /tmp/tilfluktsrom-vX.Y.Z-pwa.tar.gz tilfluktsrom-vX.Y.Z-pwa.tar.gz
- ```
-6. Install on phone: `adb install -r app/build/outputs/apk/standard/release/app-standard-release.apk`
-
## Screenshots
Use the Android emulator and Maestro to take screenshots for the README and fastlane metadata.
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 5992c73..c46b0b4 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -14,13 +14,8 @@ android {
applicationId = "no.naiv.tilfluktsrom"
minSdk = 26
targetSdk = 35
- versionCode = 12
- versionName = "1.8.0"
-
- // Deep link domain — single source of truth for manifest + Kotlin code
- val deepLinkDomain = "tilfluktsrom.naiv.no"
- buildConfigField("String", "DEEP_LINK_DOMAIN", "\"$deepLinkDomain\"")
- manifestPlaceholders["deepLinkHost"] = deepLinkDomain
+ versionCode = 11
+ versionName = "1.7.0"
}
dependenciesInfo {
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index e522483..58bf2ed 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -29,14 +29,13 @@
-
+
+ android:scheme="tilfluktsrom"
+ android:host="shelter" />
diff --git a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt
index 5f80847..e1fd8e0 100644
--- a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt
+++ b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt
@@ -143,14 +143,12 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
}
/**
- * Handle https://{domain}/shelter/{lokalId} deep link.
+ * Handle tilfluktsrom://shelter/{lokalId} deep link.
* If shelters are already loaded, select immediately; otherwise store as pending.
*/
private fun handleDeepLinkIntent(intent: Intent?) {
val uri = intent?.data ?: return
- if (uri.scheme != "https" ||
- uri.host != BuildConfig.DEEP_LINK_DOMAIN ||
- uri.path?.startsWith("/shelter/") != true) return
+ if (uri.scheme != "tilfluktsrom" || uri.host != "shelter") return
val lokalId = uri.lastPathSegment ?: return
// Clear intent data so config changes don't re-trigger
@@ -671,8 +669,8 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
/**
* Share the currently selected shelter via ACTION_SEND.
- * Includes address, capacity, geo: URI, and an HTTPS deep link
- * that opens the app (if installed) or the PWA (in browser).
+ * Includes address, capacity, geo: URI (for non-app recipients),
+ * and a tilfluktsrom:// deep link (for app users).
*/
private fun shareShelter() {
val selected = selectedShelter
@@ -682,14 +680,12 @@ class MainActivity : AppCompatActivity(), SensorEventListener {
}
val shelter = selected.shelter
- val deepLink = "https://${BuildConfig.DEEP_LINK_DOMAIN}/shelter/${shelter.lokalId}"
val body = getString(
R.string.share_body,
shelter.adresse,
shelter.plasser,
shelter.latitude,
- shelter.longitude,
- deepLink
+ shelter.longitude
)
val shareIntent = Intent(Intent.ACTION_SEND).apply {
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 048a93d..b5afd3b 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.8.0")
+ .header("User-Agent", "Tilfluktsrom/1.7.0")
.build())
})
.build()
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index 8f0f2d3..74c464b 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -60,7 +60,7 @@
Tilfluktsrom
- Tilfluktsrom: %1$s\n%2$d plasser\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s
+ Tilfluktsrom: %1$s\n%2$d plasser\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f
Ingen tilfluktsrom valgt
diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml
index 088398a..f3077e5 100644
--- a/app/src/main/res/values-nn/strings.xml
+++ b/app/src/main/res/values-nn/strings.xml
@@ -60,7 +60,7 @@
Tilfluktsrom
- Tilfluktsrom: %1$s\n%2$d plassar\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s
+ Tilfluktsrom: %1$s\n%2$d plassar\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f
Ingen tilfluktsrom valt
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 34afc98..38d09b2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -60,7 +60,7 @@
Emergency shelter
- Shelter: %1$s\n%2$d places\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f\n%5$s
+ Shelter: %1$s\n%2$d places\n%3$.6f, %4$.6f\ngeo:%3$.6f,%4$.6f
No shelter selected
diff --git a/pwa/.gitignore b/pwa/.gitignore
index 35ca4c8..b947077 100644
--- a/pwa/.gitignore
+++ b/pwa/.gitignore
@@ -1,3 +1,2 @@
node_modules/
dist/
-public/data/shelters.json
diff --git a/pwa/index.html b/pwa/index.html
index 7440b65..876bde3 100644
--- a/pwa/index.html
+++ b/pwa/index.html
@@ -6,11 +6,14 @@
+ content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' https://unpkg.com; img-src 'self' data: https://*.tile.openstreetmap.org https://unpkg.com; connect-src 'self' https://*.tile.openstreetmap.org; font-src 'self'; worker-src 'self'" />
Tilfluktsrom
-
-
-
+
+
+
+
@@ -63,6 +66,6 @@
-
+