Commit Graph
24 Commits
Author SHA1 Message Date
Ade Thompson c362d562d7 Live Activity: cheapest-in-radius Lock Screen/Dynamic Island pill
- Shared FuelBoardLiveActivityAttributes/ContentState (app + widget targets)
- FuelBoardLiveActivity Widget: ActivityConfiguration rendered by the widget
  extension - Lock Screen banner + Dynamic Island (leading/trailing/bottom,
  compact, minimal), tap anywhere -> maps:// directions to the best station
- LiveActivityManager (app side): request/update/end; mirrors the app list's
  TOP badge (selected fuel + chosen distance radius, price-then-distance
  ties); local start-date tracking for the 8h cap (this SDK's Activity has no
  startDate) - auto-restarts at 7h59m; silent no-op when disabled/denied
- Wiring: 250m/60s location hook (incl. background significant-change
  wake-ups), refresh completion, fuel/radius/unit changes, toggle flip
- Settings toggle + FuelStore persistence (keychain-backed, app-group)
- App-Info.plist: NSSupportsLiveActivities
2026-08-12 20:11:27 +01:00
FuelBoard Contributor fccd0c07ef Settings About: data source section (connection, station count, GOV.UK update time)
- Relay envelope now carries source (api|csv), stations_count, and
  data_updated (freshest price_last_updated the GOV.UK server reports,
  independent of relay sync time).
- App decodes the new envelope metadata (RelayMeta), persists it after
  each full fetch, and shows it in Settings → About → Data source:
  Connection (API/CSV), Stations count, Data updated (local-formatted).
- Older relays without the fields decode cleanly (nil meta → em-dash).
- 2 new tests for meta decode + absent-meta tolerance; 37/37 pass.
2026-08-12 16:23:41 +01:00
FuelBoard Contributor 126fdbde62 Settings Debug: device coordinates + in-range station indicator
- Debug section now shows the last device fix (lat/lng to 5dp) and its age.
- In-range indicator uses the SAME criteria as live alerts: stations selling
  the monitored fuel within the alert radius of the fix. Green dot + count
  when in range, red when none, grey while waiting for a fix.
- Shows the cheapest in-range station (name, distance, price).
- ProximityMonitor recomputes the snapshot on every location/stations
  change and on Debug-section appear; ContentView passes the live status.
- SettingsView extracted to its own property to keep TabView body within
  the compiler type-check budget. 35 tests pass.
2026-08-12 14:33:52 +01:00
FuelBoard Contributor 07521b1c98 Settings: move test notifications into hidden Debug section + dev flag
- Test-alert buttons moved out of the Alerts section into a Debug section.
- Debug section only renders when the debug flag is on; completely hidden
  otherwise (no user-facing toggle).
- Hidden toggle: tap Settings → About → Version five times to flip the
  flag (keychain + app-group storage, survives reinstall).
- About section added with version/build number.
- 35 tests pass.
2026-08-12 14:10:07 +01:00
FuelBoard Contributor 3e226ece57 Widget links maps:// directly so CarPlay can route to Apple Maps
- The widget now uses the native maps://?daddr= scheme for taps in both
  sizes. In CarPlay there is no containing app to relay through, but since
  Apple Maps IS a CarPlay app, the system may route the tap straight to
  Maps on the car display (WWDC25: widgets can launch apps in CarPlay).
- iOS keeps working via onOpenURL: the app now forwards maps:// URLs (if
  the Home Screen delivers them to the app), plus legacy fuelboard:// and
  http://maps.apple.com links from older cached timelines.
- No public API exists for a widget to detect CarPlay context, so the
  single maps:// link serves both; the app-side forward is the iOS safety
  net. 35 tests pass.
2026-08-12 13:07:44 +01:00
FuelBoard Contributor 1ff14607c5 Widget tap relay via fuelboard:// scheme; full station names; no check-again
- WidgetKit widgets can only open their containing app — the Link URL is
  delivered to FuelBoard via onOpenURL, never opened directly in Maps. The
  widget now links to a registered fuelboard://directions?lat=&lng= URL,
  and FuelBoardApp forwards it to native maps://?daddr= directions.
  (http://maps.apple.com and raw maps:// both silently dropped in-app.)
- Widget rows (small + medium) now show the full station name (station.name)
  instead of just the brand.
- Onboarding network page: removed the 'Check again' secondary screen after
  the Local Network prompt — Open Settings remains the only retry path.
  35 tests pass.
2026-08-12 12:54:08 +01:00
FuelBoard Contributor 9ce0c83d66 Widget opens Maps via maps://; onboarding prompts after Continue; forced first fetch
- 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.
2026-08-12 12:41:19 +01:00
FuelBoard Contributor 1f50d7dcf4 Tied cheapest stations become notification action buttons
When several stations share the cheapest price within the radius (within
0.01p), the alert registers a dynamic UNNotificationCategory with up to
4 action buttons (brand + distance, nearest first) and taps open
directions to the chosen station. Shared FuelStore.tiedStations helper
used by both the live geofence path and the Settings real-data test;
35 tests pass.
2026-08-12 10:48:08 +01:00
FuelBoard Contributor 46d5d45c93 Alerts choose their own fuel, independent of the Stations tab
The proximity monitor was tied to the Stations-tab fuel selection, so
switching the list to another fuel silently re-targeted geofences. Now the
Alerts tab has its own 'Fuel to monitor' picker (persisted as
fuelboard.alertsFuel):
- Monitor reads loadAlertsFuel() on init/background relaunch
- Changing the alerts fuel re-registers geofences around stations selling
  that fuel only
- Favourites priority slots stay scoped to the monitored fuel
- Tests: alerts fuel round-trip + default (33/33 passing)
2026-08-12 08:51:31 +01:00
FuelBoard Contributor 35e0adaf0b Favourites are fuel-scoped: starring pins the station for one fuel only
Fixing the bug where favouriting an Unleaded entry also created a Diesel
favourite. Favourites are now [FavouriteEntry] = (station, fuel) pairs:
- Starring a row pins it only for the fuel being viewed
- Favourites tabs show only fuels that actually have favourites
- Geofence monitor gives priority slots only to favourites matching the
  monitored fuel
- Tests updated + new fuel-scoping test (31/31 passing)
2026-08-12 08:31:08 +01:00
FuelBoard Contributor 44c6c38536 Add Settings tab: distance units toggle, onboarding replay, £4.99 tip; drop E10/E5 from labels
- FuelType labels: 'Unleaded (E10)'/'Premium (E5)' -> 'Unleaded'/'Premium'
- New DistanceUnit (miles/km) preference; all app + widget distances,
  radii and alert text convert/display in the chosen unit
- Settings tab (4th tab): segmented miles/km picker, 'Show introduction'
  replay button (onboarding moved out of Alerts tab), StoreKit tip £4.99
- ProximityMonitor + widget notifications use the chosen unit
- Tests: label expectations updated, DistanceUnit conversion + format tests
2026-08-12 07:46:08 +01:00
FuelBoard Contributor fb79cf0788 Add first-launch onboarding with location + notification permission prompts
- OnboardingView: 4-page flow (welcome + features, location, notifications, done)
- Triggers system prompts in-context via OnboardingPermissionPrompter
- Shown at initial launch only (FuelStore.onboardingCompleted flag, app-group defaults)
- Test hook: 'Show onboarding (testing)' button at bottom of Alerts tab
2026-08-12 07:10:54 +01:00
FuelBoard Contributor 05f3ef0a70 Add (E10)/(E5) bracket labels to Unleaded/Premium in picker and descriptions 2026-08-11 22:41:50 +01:00
FuelBoard Contributor aee890e2a8 Title-case station names: fix Sainsbury's apostrophe, lowercase/mixed names, hyphen/paren chunks, acronyms; re-sanitize cache on load 2026-08-11 21:23:36 +01:00
FuelBoard Contributor cf9765be7b Fetch full-UK dump (no radius/limit); stations in app-group defaults only; alert path keeps focused radius fetch 2026-08-11 19:30:02 +01:00
FuelBoard Contributor 213f93aa04 Results filter is now search radius in miles (5/10/15); relay fetch scoped to radius, limit 500; changing miles re-fetches; caption shows stations within N miles 2026-08-11 18:02:23 +01:00
FuelBoard Contributor 8230daa249 Cache-first refresh policy: auto-fetch at most twice a day (12h gate), no fetch on launch/foreground/location/fuel-switch, pull-to-refresh forces; geofences still follow location 2026-08-11 17:43:11 +01:00
FuelBoard Contributor 75629b39b5 Price right-aligned on second row; word-capitalise station titles (keep BP/MFG/ASDA) 2026-08-11 15:40:19 +01:00
FuelBoard Contributor 60d25164d6 Tabs (Stations/Favourites/Alerts): favourites with cheapest-first ranking, proximity geofence alerts (favourites priority, 3km default radius, 1h dedup), Always location + background mode 2026-08-11 15:17:26 +01:00
FuelBoard Contributor d220023917 Round brand logos in station rows: 11 bundled assets (Simple Icons + Wikimedia), fuel-pump fallback for unknown brands 2026-08-11 15:00:26 +01:00
FuelBoard Contributor acb5c33578 Remove Location status section; add 10/25/50/75/100 station limit picker; refresh location every foreground 2026-08-11 14:41:39 +01:00
FuelBoard Contributor d9ec2f8c35 Sort toggle (cheapest/closest) + RAG value rating per station with TOP badge 2026-08-11 14:14:07 +01:00
FuelBoard Contributor 4f5f1999a9 Location-driven results: widget fetches its own location (async, cache fallback), app auto-requests on first launch, Halifax sample stations 2026-08-11 14:03:41 +01:00
FuelBoard Contributor b0a5b5a326 Scaffold FuelBoard: petrol price widget + app (sample data, Maps deep-links, provider seam for Fuel Finder API) 2026-08-11 13:54:56 +01:00