Widget Favourites filter: pinned stations cheapest-first, no radius

- New Sort by value 'Favourites' in Edit Widget (per-widget config).
- ParameterSummary hides the Distance picker when Favourites is selected
  (favourites are not radius-bound).
- Favourites mode reads keychain favourites (shared access group works on
  SideStore free even without App Groups), filters to the widget's fuel,
  refreshes prices from a focused relay fetch when in range, and ranks
  cheapest-first with distance tiebreak. Not radius-filtered.
- App now re-saves refreshed favourites to keychain after every fetch so
  the widget shows current prices instead of star-time snapshots.
- Empty state + headings adapt to favourites mode. 35 tests pass.
This commit is contained in:
FuelBoard Contributor
2026-08-12 13:45:42 +01:00
parent 3e226ece57
commit 5246f41c48
3 changed files with 107 additions and 45 deletions
+19
View File
@@ -24,12 +24,14 @@ enum WidgetFuel: String, AppEnum, CaseIterable, Codable {
enum WidgetSort: String, AppEnum, CaseIterable, Codable {
case cheapest
case closest
case favourites
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Sort by"
static var caseDisplayRepresentations: [WidgetSort: DisplayRepresentation] = [
.cheapest: "Cheapest",
.closest: "Closest",
.favourites: "Favourites",
]
}
@@ -67,4 +69,21 @@ struct FuelBoardWidgetConfigurationIntent: WidgetConfigurationIntent {
@Parameter(title: "Distance", default: .five)
var distance: WidgetDistance
/// Edit-Widget UI: Favourites ranks pinned stations cheapest-first and is
/// not radius-bound, so the Distance picker is hidden in that mode.
static var parameterSummary: some ParameterSummary {
When(\.$sort, .equalTo, WidgetSort.favourites) {
Summary("Show \(\.$fuel) favourites") {
\.$fuel
\.$sort
}
} otherwise: {
Summary("Show \(\.$fuel) by \(\.$sort) within \(\.$distance)") {
\.$fuel
\.$sort
\.$distance
}
}
}
}