import AppIntents import Foundation // Per-widget configuration intent (iOS 17+). Every widget instance carries // its OWN fuel + sort choices, edited directly on the home screen (long-press // → Edit Widget), independent of what the app has selected. This is what // allows several FuelBoard widgets to show different fuels/orderings side by // side. enum WidgetFuel: String, AppEnum, CaseIterable, Codable { case e10 case e5 case diesel static var typeDisplayRepresentation: TypeDisplayRepresentation = "Fuel" static var caseDisplayRepresentations: [WidgetFuel: DisplayRepresentation] = [ .e10: "Unleaded", .e5: "Premium", .diesel: "Diesel", ] } 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", ] } enum WidgetDistance: String, AppEnum, CaseIterable, Codable { case five case ten case fifteen static var typeDisplayRepresentation: TypeDisplayRepresentation = "Distance" static var caseDisplayRepresentations: [WidgetDistance: DisplayRepresentation] = [ .five: "5 miles", .ten: "10 miles", .fifteen: "15 miles", ] /// Mirror the app's units setting: the Edit-Widget picker labels show the /// real distance in the user's chosen unit — "5 miles" in miles mode, /// "8 km" in km mode (same stored value, labelled truthfully). Keeps the /// widget config consistent with the Stations/Alerts pickers. var displayRepresentation: DisplayRepresentation { let unit = FuelStore.loadDistanceUnit() let shown = unit.displayMiles(miles) return DisplayRepresentation(stringLiteral: "\(shown) \(unit.label(for: Double(shown)))") } var miles: Int { switch self { case .five: return 5 case .ten: return 10 case .fifteen: return 15 } } } struct FuelBoardWidgetConfigurationIntent: WidgetConfigurationIntent { static var title: LocalizedStringResource = "Fuel & Sort" static var description = IntentDescription("Which fuel, ordering and search radius this widget shows.") @Parameter(title: "Fuel", default: .e10) var fuel: WidgetFuel @Parameter(title: "Sort by", default: .cheapest) var sort: WidgetSort @Parameter(title: "Distance", default: .five) var distance: WidgetDistance /// Edit-Widget UI: the Distance picker only makes sense for Cheapest /// ordering — Closest is inherently "nearest within range" and Favourites /// is not radius-bound. Show it for Cheapest only; hide for both others. static var parameterSummary: some ParameterSummary { When(\.$sort, .equalTo, WidgetSort.cheapest) { Summary("Show \(\.$fuel) by \(\.$sort) within \(\.$distance)") { \.$fuel \.$sort \.$distance } } otherwise: { When(\.$sort, .equalTo, WidgetSort.favourites) { Summary("Show \(\.$fuel) favourites") { \.$fuel \.$sort } } otherwise: { Summary("Show \(\.$fuel) by \(\.$sort)") { \.$fuel \.$sort } } } } }