From 9ce0c83d66e135a5c93523f30dfc997207437487 Mon Sep 17 00:00:00 2001 From: FuelBoard Contributor Date: Wed, 12 Aug 2026 12:41:19 +0100 Subject: [PATCH] Widget opens Maps via maps://; onboarding prompts after Continue; forced first fetch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Widget tap-to-directions now uses the native maps:// scheme instead of http://maps.apple.com. The universal-link http URL failed to open from a widget and fell back to launching the containing app; maps:// opens Apple Maps directly for both small (whole widget) and medium (per row). - Onboarding: removed the Skip button (mandatory flow), and system prompts (location, notifications, local network) now fire only when the user taps Continue/Allow on each page — not when the page appears. Pages auto-advance once a permission is granted. - After 'Start Using FuelBoard' the first data fetch is forced, so a reinstall that leaves a recent lastRefresh in app-group defaults can no longer skip the fetch and leave the station list empty. 35 tests pass. --- FuelBoard/ContentView.swift | 9 +++-- FuelBoard/OnboardingView.swift | 46 +++++++++++++++----------- FuelBoardWidgets/FuelPriceWidget.swift | 4 +-- Shared/FuelStore.swift | 5 ++- 4 files changed, 38 insertions(+), 26 deletions(-) diff --git a/FuelBoard/ContentView.swift b/FuelBoard/ContentView.swift index 9dd84d5..e8c9b6f 100644 --- a/FuelBoard/ContentView.swift +++ b/FuelBoard/ContentView.swift @@ -182,13 +182,16 @@ struct ContentView: View { .onChange(of: showOnboarding) { _, showing in // After onboarding finishes (or the test re-run is dismissed), // begin foreground location tracking if permission allows, and - // run the first data fetch (the relay probe during onboarding - // already surfaced the Local Network prompt). + // run the FIRST data fetch. This must be a forced refresh: a + // reinstall may leave a recent `lastRefresh` in the app-group + // defaults (which survive app deletion), which would make the + // cache-gated refresh skip the fetch and leave the station list + // empty on a brand-new install. if !showing, FuelStore.loadHasCompletedOnboarding() { locationManager.startForegroundTracking() monitor.update(stations: stations, favourites: refreshedFavourites, fuel: alertsFuel, radiusKM: alertsRadius) - Task { await refresh() } + Task { await refresh(force: true) } } } .onChange(of: scenePhase) { _, newPhase in diff --git a/FuelBoard/OnboardingView.swift b/FuelBoard/OnboardingView.swift index 4d6696e..08afcab 100644 --- a/FuelBoard/OnboardingView.swift +++ b/FuelBoard/OnboardingView.swift @@ -18,15 +18,8 @@ struct OnboardingView: View { var body: some View { VStack(spacing: 0) { - // Top bar: skip + page dots + // Top bar: page dots only — onboarding is mandatory, no skip. HStack { - if page < totalPages - 1 { - Button("Skip") { finish() } - .font(.subheadline) - .foregroundStyle(.secondary) - } else { - Color.clear.frame(width: 40, height: 20) - } Spacer() HStack(spacing: 8) { ForEach(0..