diff --git a/.maestro/screenshots-nn.yaml b/.maestro/screenshots-nn.yaml deleted file mode 100644 index dae75a5..0000000 --- a/.maestro/screenshots-nn.yaml +++ /dev/null @@ -1,72 +0,0 @@ -# Maestro flow: Capture F-Droid screenshots for nn-NO (Nynorsk) -# -# Nynorsk is not supported as a system locale on stock Android. -# This flow uses per-app locale (API 33+) which requires NOT clearing app state, -# since clearState wipes per-app locale settings. -# -# Run the main screenshots.yaml first (any locale) so that map tiles are cached. -# Then set the per-app locale and run this flow: -# -# adb shell "cmd locale set-app-locales no.naiv.tilfluktsrom --locales nn" -# maestro test .maestro/screenshots-nn.yaml - -appId: no.naiv.tilfluktsrom - -env: - OUTPUT_DIR: "fastlane/metadata/android" - ---- - -# Mock GPS: Bergen centrum (Torgallmenningen) -- setLocation: - latitude: 60.3913 - longitude: 5.3221 - -# Launch WITHOUT clearing state (preserves per-app locale and cached tiles) -- launchApp: - appId: no.naiv.tilfluktsrom - clearState: false - permissions: - android.permission.ACCESS_FINE_LOCATION: allow - android.permission.ACCESS_COARSE_LOCATION: allow - -# Wait for shelter data to load -- extendedWaitUntil: - visible: - id: "statusText" - timeout: 15000 - -# Wait for shelter list to populate -- extendedWaitUntil: - visible: - id: "shelterList" - timeout: 15000 - -- waitForAnimationToEnd - -# Screenshot 1: Map view -- takeScreenshot: - path: "${OUTPUT_DIR}/nn-NO/images/phoneScreenshots/1_map_view" - -# Screenshot 2: Tap second shelter -- tapOn: "Håkonsgaten 5" -- waitForAnimationToEnd -- takeScreenshot: - path: "${OUTPUT_DIR}/nn-NO/images/phoneScreenshots/2_shelter_selected" - -# Screenshot 3: Compass view -- tapOn: - id: "toggleViewFab" -- waitForAnimationToEnd -- takeScreenshot: - path: "${OUTPUT_DIR}/nn-NO/images/phoneScreenshots/3_compass_view" - -# Screenshot 4: Civil defense dialog -- tapOn: - id: "toggleViewFab" -- waitForAnimationToEnd -- tapOn: - id: "infoButton" -- waitForAnimationToEnd -- takeScreenshot: - path: "${OUTPUT_DIR}/nn-NO/images/phoneScreenshots/4_civil_defense_info" diff --git a/.maestro/screenshots.yaml b/.maestro/screenshots.yaml deleted file mode 100644 index de15230..0000000 --- a/.maestro/screenshots.yaml +++ /dev/null @@ -1,95 +0,0 @@ -# Maestro flow: Capture F-Droid screenshots for Tilfluktsrom -# -# Usage (from project root): -# maestro test .maestro/screenshots.yaml -# -# With a specific locale: -# LOCALE=nb-NO maestro test .maestro/screenshots.yaml -# -# Prerequisites: -# - Android emulator (API 31+) or device running -# - App installed: ./gradlew installDebug -# - Internet connection (needed for map tile caching) -# - Install Maestro: curl -Ls https://get.maestro.mobile.dev | bash -# -# GPS is mocked to Bergen centrum (Torgallmenningen area), -# which has several shelters within walking distance. - -appId: no.naiv.tilfluktsrom - -env: - LOCALE: "en-US" - OUTPUT_DIR: "fastlane/metadata/android" - ---- - -# Mock GPS: Bergen centrum (Torgallmenningen) -- setLocation: - latitude: 60.3913 - longitude: 5.3221 - -# Grant location permission and launch with fresh state -- launchApp: - appId: no.naiv.tilfluktsrom - clearState: true - permissions: - android.permission.ACCESS_FINE_LOCATION: allow - android.permission.ACCESS_COARSE_LOCATION: allow - -# Wait for shelter data to load from bundled asset. -- extendedWaitUntil: - visible: - id: "statusText" - timeout: 15000 - -# The app shows a map caching prompt on first GPS fix when no cache exists. -# Tap "Cache map" and wait for caching to complete (~15s). -# This prevents the overlay from re-appearing on subsequent GPS updates. -- extendedWaitUntil: - visible: - id: "loadingOkButton" - timeout: 15000 - -- tapOn: - id: "loadingOkButton" - -# Wait for caching to finish (4 zoom levels x 9 grid points x 300ms ≈ 11s + network) -- extendedWaitUntil: - notVisible: - id: "loadingOverlay" - timeout: 30000 - -# Let the map settle and shelter list populate after caching -- waitForAnimationToEnd -- extendedWaitUntil: - visible: - id: "shelterList" - timeout: 10000 - -# Screenshot 1: Map view with shelter markers and bottom sheet -- takeScreenshot: - path: "${OUTPUT_DIR}/${LOCALE}/images/phoneScreenshots/1_map_view" - -# Screenshot 2: Tap the second shelter (Håkonsgaten 5) to show a different selection. -# Shelter addresses are locale-independent, so this works in all languages. -- tapOn: "Håkonsgaten 5" -- waitForAnimationToEnd -- takeScreenshot: - path: "${OUTPUT_DIR}/${LOCALE}/images/phoneScreenshots/2_shelter_selected" - -# Screenshot 3: Switch to compass view -- tapOn: - id: "toggleViewFab" -- waitForAnimationToEnd -- takeScreenshot: - path: "${OUTPUT_DIR}/${LOCALE}/images/phoneScreenshots/3_compass_view" - -# Screenshot 4: Switch back to map, open civil defense info dialog -- tapOn: - id: "toggleViewFab" -- waitForAnimationToEnd -- tapOn: - id: "infoButton" -- waitForAnimationToEnd -- takeScreenshot: - path: "${OUTPUT_DIR}/${LOCALE}/images/phoneScreenshots/4_civil_defense_info" diff --git a/.maestro/take-screenshots.sh b/.maestro/take-screenshots.sh deleted file mode 100755 index d44bb4e..0000000 --- a/.maestro/take-screenshots.sh +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env bash -# Generate F-Droid screenshots for all locales using Maestro. -# -# Prerequisites: -# 1. Install Maestro: curl -Ls https://get.maestro.mobile.dev | bash -# 2. Start an Android emulator (API 33+): emulator -avd -# 3. Build and install the app: ./gradlew installDebug -# 4. Run this script: .maestro/take-screenshots.sh -# -# Screenshots are saved directly into fastlane/metadata/android//images/ -# -# Locale handling: -# - en-US and nb-NO use system locale (settings put system system_locales) -# - nn-NO (Nynorsk) requires per-app locale since Android doesn't support -# Nynorsk as a system locale — it falls back to Bokmål - -set -euo pipefail -cd "$(dirname "$0")/.." - -FLOW=".maestro/screenshots.yaml" -FLOW_NN=".maestro/screenshots-nn.yaml" - -restart_framework() { - adb shell stop 2>/dev/null - sleep 2 - adb shell start 2>/dev/null - sleep 8 -} - -ensure_root() { - adb root 2>/dev/null || true - sleep 1 -} - -echo "=== Ensuring root access ===" -ensure_root - -# --- en-US --- -echo "=== Capturing screenshots for en-US ===" -mkdir -p "fastlane/metadata/android/en-US/images/phoneScreenshots" -rm -f "fastlane/metadata/android/en-US/images/.gitkeep" - -adb shell "settings put system system_locales en-US" -restart_framework - -sed -i 's/LOCALE: ".*"/LOCALE: "en-US"/' "$FLOW" -maestro test "$FLOW" -echo "=== Done: en-US ===" -echo "" - -# --- nb-NO --- -echo "=== Capturing screenshots for nb-NO ===" -mkdir -p "fastlane/metadata/android/nb-NO/images/phoneScreenshots" -rm -f "fastlane/metadata/android/nb-NO/images/.gitkeep" - -adb shell "settings put system system_locales nb-NO" -restart_framework - -sed -i 's/LOCALE: ".*"/LOCALE: "nb-NO"/' "$FLOW" -maestro test "$FLOW" -sed -i 's/LOCALE: "nb-NO"/LOCALE: "en-US"/' "$FLOW" -echo "=== Done: nb-NO ===" -echo "" - -# --- nn-NO (Nynorsk) --- -# Android doesn't support nn as a system locale, so we use per-app locale. -# The main flow must have run first to cache map tiles (nn flow uses clearState: false). -echo "=== Capturing screenshots for nn-NO ===" -mkdir -p "fastlane/metadata/android/nn-NO/images/phoneScreenshots" -rm -f "fastlane/metadata/android/nn-NO/images/.gitkeep" - -adb shell "am force-stop no.naiv.tilfluktsrom" -adb shell "cmd locale set-app-locales no.naiv.tilfluktsrom --locales nn" -sleep 2 - -maestro test "$FLOW_NN" -echo "=== Done: nn-NO ===" -echo "" - -# Restore en-US -adb shell "settings put system system_locales en-US" -adb shell "cmd locale set-app-locales no.naiv.tilfluktsrom --locales en" -restart_framework - -echo "All screenshots captured." -echo "Check: fastlane/metadata/android/*/images/phoneScreenshots/" diff --git a/STANDING_ON_SHOULDERS.md b/STANDING_ON_SHOULDERS.md deleted file mode 100644 index e33c1bd..0000000 --- a/STANDING_ON_SHOULDERS.md +++ /dev/null @@ -1,162 +0,0 @@ -# Standing on Shoulders - -## How many people made this app possible? - -Tilfluktsrom is a small Android app — about 900 source files — that helps -Norwegians find their nearest public shelter in an emergency. One person built -it in under a day. But that was only possible because of the accumulated work of -roughly **100,000–120,000 identifiable people**, spanning decades, countries, and -disciplines. - -This document traces the human effort behind every layer of the stack. - ---- - -## Layer 0: Physical Infrastructure — GPS & Sensors (~10,500 people) - -| Component | Role | Est. people | -|---|---|---| -| GPS constellation | 31 satellites, maintained by US Space Force | ~5,000 | -| Magnetometer/compass sensors | Enable the direction arrow to point at shelters | ~500 | -| ARM architecture | The CPU instruction set running every Android device | ~5,000 | - -Before a single line of code runs, hardware designed by tens of thousands of -engineers must be in orbit, in your pocket, and on the circuit board. - -## Layer 1: Internet & Standards (~5,250 people) - -| Component | Role | Est. people | -|---|---|---| -| TCP/IP, DNS, HTTP, TLS | The protocols that carry shelter data from server to phone | ~5,000 | -| GeoJSON specification | The format the shelter data is published in (IETF RFC 7946) | ~50 | -| EPSG / coordinate reference systems | The math behind UTM33N → WGS84 coordinate conversion | ~200 | - -## Layer 2: Operating Systems & Runtimes (~27,200 people) - -| Component | Role | Est. people | -|---|---|---| -| Linux kernel | Foundation of Android; ~20,000 documented unique contributors | ~20,000 | -| Android (AOSP) | The mobile OS, built on Linux by Google + community | ~5,000 | -| JVM / OpenJDK + Java | The language runtime Kotlin compiles to | ~2,000 | -| ART (Android Runtime) | Replaced Dalvik; runs the compiled bytecode | ~200 | - -## Layer 3: Programming Languages (~1,200 people) - -| Language | Origin | Est. people | -|---|---|---| -| Kotlin | JetBrains (Czech Republic/Russia) + community | ~500 | -| TypeScript | Microsoft + community (for the PWA) | ~500 | -| Groovy / Kotlin DSL | Gradle build scripts | ~200 | - -## Layer 4: Build Tools & Dev Infrastructure (~5,400 people) - -| Tool | Role | Est. people | -|---|---|---| -| Gradle | Build automation | ~500 | -| Android Gradle Plugin | Android-specific build pipeline | ~200 | -| KSP (Kotlin Symbol Processing) | Code generation for Room database | ~100 | -| R8 / ProGuard | Release minification and optimization | ~100 | -| Vite | PWA bundler | ~800 | -| Bun | Package manager and JS runtime | ~400 | -| Git | Version control | ~1,500 | -| Android Studio / IntelliJ | IDE (JetBrains + Google) | ~1,500 | -| Maven Central, Google Maven, npm | Package registry infrastructure | ~300 | - -## Layer 5: Libraries — Android App (~2,550 people) - -| Library | What it does | Est. people | -|---|---|---| -| AndroidX (Core, AppCompat, Activity, Lifecycle) | UI and app architecture foundation | ~800 | -| Material Design | Visual design language, research, and components | ~500 | -| ConstraintLayout | Flexible screen layouts | ~100 | -| Room | Type-safe SQLite wrapper for the shelter cache | ~200 | -| WorkManager | Periodic home screen widget updates | ~150 | -| Kotlinx Coroutines | Async data loading without blocking the UI | ~200 | -| OkHttp (Square) | Downloads the GeoJSON ZIP from Geonorge | ~200 | -| OSMDroid | Offline OpenStreetMap rendering | ~150 | -| Play Services Location | FusedLocationProvider for precise GPS | ~200 | -| SQLite | The embedded database engine | ~50 | - -## Layer 6: Libraries — PWA (~1,350 people) - -| Library | Role | Est. people | -|---|---|---| -| Leaflet | Interactive web maps (created in Ukraine) | ~800 | -| leaflet.offline | Offline tile caching | ~20 | -| idb | IndexedDB wrapper for offline storage | ~30 | -| vite-plugin-pwa | Service worker and Workbox integration | ~100 | -| Vitest | Test framework | ~400 | - -## Layer 7: Data — The Content That Makes It Useful (~56,000 people) - -| Source | Role | Est. people | -|---|---|---| -| OpenStreetMap | Global map data; ~2M registered mappers, ~10,000+ active in Norway | ~50,000 | -| Kartverket / Geonorge | Norwegian Mapping Authority; national geodata infrastructure | ~800 | -| DSB (Direktoratet for samfunnssikkerhet og beredskap) | Created and maintains the public shelter registry | ~200 | -| The shelter builders | Construction, engineering, civil defense planning since the Cold War | ~5,000+ | - -The app's data exists because of Cold War civil defense planning. The shelters -were built in the 1950s–80s, digitized by DSB, published via Geonorge's open -data mandate — a chain of decisions spanning 70 years that now fits in a 320 KB -GeoJSON file. - -## Layer 8: AI-Assisted Development (~6,000 people) - -| Component | Role | Est. people | -|---|---|---| -| Anthropic / Claude | Researchers, engineers, safety team | ~1,000 | -| ML research lineage | Transformers, attention, RLHF, scaling laws — across academia & industry | ~5,000 | -| Training data | The collective written output of humanity | incalculable | - -## Layer 9: Distribution (~500 people) - -| Component | Role | Est. people | -|---|---|---| -| F-Droid | Open-source app store infrastructure and review | ~300 | -| Fastlane | Metadata and screenshot tooling | ~200 | - ---- - -## Summary - -| Layer | People | -|---|---| -| Physical infrastructure (GPS, ARM, sensors) | ~10,500 | -| Internet & standards | ~5,250 | -| Operating systems & runtimes | ~27,200 | -| Programming languages | ~1,200 | -| Build tools & dev infrastructure | ~5,400 | -| Direct libraries (Android) | ~2,550 | -| Direct libraries (PWA) | ~1,350 | -| Data (maps, shelters, geodesy) | ~56,000 | -| AI-assisted development | ~6,000 | -| Distribution | ~500 | -| **Conservative total** | **~116,000** | - -This is conservative. It excludes: - -- The millions of OSM mappers globally whose edits feed the tile rendering pipeline -- Hardware manufacturing (semiconductor fabs, device assembly — millions of workers) -- The educators who taught all these people their craft -- The civil defense planners who decided Norway needed public shelters -- The mathematicians behind Haversine, UTM projections, and geodesy going back centuries - -Including OpenStreetMap's full contributor base and hardware, the number crosses -**2 million** easily. - ---- - -## Perspective - -For every line of application code, roughly 100,000 people made the tools, data, -and infrastructure that line depends on. No single company, country, or -organization could have built this stack alone. Linux (Finland → global), Kotlin -(Czech Republic/Russia → JetBrains), OSM (UK → global), GPS (US military → -civilian), Leaflet (Ukraine), SQLite (US, public domain) — this emergency app is -a product of genuine global cooperation. - -The fact that one person can build a working, offline-capable emergency app in -under a day is arguably one of the most remarkable expressions of accumulated -human cooperation — and almost none of it was coordinated by any central -authority. diff --git a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt index 2f11f27..af96248 100644 --- a/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt +++ b/app/src/main/java/no/naiv/tilfluktsrom/MainActivity.kt @@ -298,11 +298,7 @@ class MainActivity : AppCompatActivity(), SensorEventListener { Toast.makeText(this@MainActivity, R.string.error_shelter_not_found, Toast.LENGTH_SHORT).show() } } - if (currentLocation != null) { - updateNearestShelters(currentLocation!!) - } else { - showWaitingForLocation() - } + currentLocation?.let { updateNearestShelters(it) } } } catch (e: CancellationException) { throw e @@ -728,15 +724,6 @@ class MainActivity : AppCompatActivity(), SensorEventListener { binding.loadingOverlay.visibility = View.GONE } - /** - * Show a waiting state in the bottom sheet when shelters are loaded - * but no GPS fix is available yet. - */ - private fun showWaitingForLocation() { - binding.selectedShelterAddress.text = getString(R.string.status_no_location) - binding.selectedShelterDetails.text = getString(R.string.status_shelters_loaded, allShelters.size) - } - /** Persist last GPS fix so the widget can use it even when the app isn't running. */ private fun saveLastLocation(location: Location) { getSharedPreferences("widget_prefs", Context.MODE_PRIVATE).edit() diff --git a/fastlane/metadata/android/en-US/changelogs/8.txt b/fastlane/metadata/android/en-US/changelogs/8.txt deleted file mode 100644 index c6d65db..0000000 --- a/fastlane/metadata/android/en-US/changelogs/8.txt +++ /dev/null @@ -1,2 +0,0 @@ -- Show waiting status when GPS is unavailable instead of empty shelter list -- Add F-Droid screenshots for all locales diff --git a/fastlane/metadata/android/en-US/images/.gitkeep b/fastlane/metadata/android/en-US/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/1_map_view.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/1_map_view.png deleted file mode 100644 index 5d9675f..0000000 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/1_map_view.png and /dev/null differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/2_shelter_selected.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/2_shelter_selected.png deleted file mode 100644 index 85dcd32..0000000 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/2_shelter_selected.png and /dev/null differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/3_compass_view.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/3_compass_view.png deleted file mode 100644 index 22f723e..0000000 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/3_compass_view.png and /dev/null differ diff --git a/fastlane/metadata/android/en-US/images/phoneScreenshots/4_civil_defense_info.png b/fastlane/metadata/android/en-US/images/phoneScreenshots/4_civil_defense_info.png deleted file mode 100644 index c732755..0000000 Binary files a/fastlane/metadata/android/en-US/images/phoneScreenshots/4_civil_defense_info.png and /dev/null differ diff --git a/fastlane/metadata/android/nb-NO/changelogs/8.txt b/fastlane/metadata/android/nb-NO/changelogs/8.txt deleted file mode 100644 index 49bed3b..0000000 --- a/fastlane/metadata/android/nb-NO/changelogs/8.txt +++ /dev/null @@ -1,2 +0,0 @@ -- Vis ventestatus når GPS ikke er tilgjengelig i stedet for tom tilfluktsromliste -- Legg til F-Droid-skjermbilder for alle språk diff --git a/fastlane/metadata/android/nb-NO/images/.gitkeep b/fastlane/metadata/android/nb-NO/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/1_map_view.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/1_map_view.png deleted file mode 100644 index bddc652..0000000 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/1_map_view.png and /dev/null differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/2_shelter_selected.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/2_shelter_selected.png deleted file mode 100644 index 2fe8b38..0000000 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/2_shelter_selected.png and /dev/null differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/3_compass_view.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/3_compass_view.png deleted file mode 100644 index a89d2a2..0000000 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/3_compass_view.png and /dev/null differ diff --git a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/4_civil_defense_info.png b/fastlane/metadata/android/nb-NO/images/phoneScreenshots/4_civil_defense_info.png deleted file mode 100644 index 9b5edb0..0000000 Binary files a/fastlane/metadata/android/nb-NO/images/phoneScreenshots/4_civil_defense_info.png and /dev/null differ diff --git a/fastlane/metadata/android/nn-NO/changelogs/8.txt b/fastlane/metadata/android/nn-NO/changelogs/8.txt deleted file mode 100644 index d96550b..0000000 --- a/fastlane/metadata/android/nn-NO/changelogs/8.txt +++ /dev/null @@ -1,2 +0,0 @@ -- Vis ventestatus når GPS ikkje er tilgjengeleg i staden for tom tilfluktsromliste -- Legg til F-Droid-skjermbilete for alle språk diff --git a/fastlane/metadata/android/nn-NO/images/.gitkeep b/fastlane/metadata/android/nn-NO/images/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/fastlane/metadata/android/nn-NO/images/phoneScreenshots/1_map_view.png b/fastlane/metadata/android/nn-NO/images/phoneScreenshots/1_map_view.png deleted file mode 100644 index 2a3b179..0000000 Binary files a/fastlane/metadata/android/nn-NO/images/phoneScreenshots/1_map_view.png and /dev/null differ diff --git a/fastlane/metadata/android/nn-NO/images/phoneScreenshots/2_shelter_selected.png b/fastlane/metadata/android/nn-NO/images/phoneScreenshots/2_shelter_selected.png deleted file mode 100644 index 037c472..0000000 Binary files a/fastlane/metadata/android/nn-NO/images/phoneScreenshots/2_shelter_selected.png and /dev/null differ diff --git a/fastlane/metadata/android/nn-NO/images/phoneScreenshots/3_compass_view.png b/fastlane/metadata/android/nn-NO/images/phoneScreenshots/3_compass_view.png deleted file mode 100644 index 1128bb9..0000000 Binary files a/fastlane/metadata/android/nn-NO/images/phoneScreenshots/3_compass_view.png and /dev/null differ diff --git a/fastlane/metadata/android/nn-NO/images/phoneScreenshots/4_civil_defense_info.png b/fastlane/metadata/android/nn-NO/images/phoneScreenshots/4_civil_defense_info.png deleted file mode 100644 index da75ca3..0000000 Binary files a/fastlane/metadata/android/nn-NO/images/phoneScreenshots/4_civil_defense_info.png and /dev/null differ diff --git a/version.properties b/version.properties index e9b517b..ef64dbc 100644 --- a/version.properties +++ b/version.properties @@ -1,4 +1,4 @@ versionMajor=1 -versionMinor=5 -versionPatch=0 -versionCode=8 +versionMinor=4 +versionPatch=1 +versionCode=7