Widget config: Distance picker as AppEntity so labels resolve dynamically from the app's units (AppEnum labels are static)
This commit is contained in:
@@ -35,35 +35,36 @@ enum WidgetSort: String, AppEnum, CaseIterable, Codable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
enum WidgetDistance: String, AppEnum, CaseIterable, Codable {
|
// Per-widget distance filter. Modelled as an AppEntity (not an AppEnum) so
|
||||||
case five
|
// the option labels can mirror the app's units setting at render time: an
|
||||||
case ten
|
// AppEnum's caseDisplayRepresentations are STATIC, so the Edit-Widget picker
|
||||||
case fifteen
|
// would always show "5 miles / 10 miles / 15 miles" regardless of the app's
|
||||||
|
// km mode. An entity query resolves labels per value, so they can read the
|
||||||
|
// shared unit preference ("8 km" in km mode).
|
||||||
|
struct WidgetDistance: AppEntity, Identifiable, Hashable, Codable {
|
||||||
|
/// The distance in miles (5/10/15) — the persisted value. Labels are
|
||||||
|
/// unit-aware, the stored value stays in miles.
|
||||||
|
let id: Int
|
||||||
|
|
||||||
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Distance"
|
var miles: Int { id }
|
||||||
|
|
||||||
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 {
|
var displayRepresentation: DisplayRepresentation {
|
||||||
let unit = FuelStore.loadDistanceUnit()
|
let unit = FuelStore.loadDistanceUnit()
|
||||||
let shown = unit.displayMiles(miles)
|
let shown = unit.displayMiles(id)
|
||||||
return DisplayRepresentation(stringLiteral: "\(shown) \(unit.label(for: Double(shown)))")
|
return DisplayRepresentation(stringLiteral: "\(shown) \(unit.label(for: Double(shown)))")
|
||||||
}
|
}
|
||||||
|
|
||||||
var miles: Int {
|
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Distance"
|
||||||
switch self {
|
static var defaultQuery = WidgetDistanceQuery()
|
||||||
case .five: return 5
|
}
|
||||||
case .ten: return 10
|
|
||||||
case .fifteen: return 15
|
struct WidgetDistanceQuery: EntityQuery {
|
||||||
}
|
func entities(for identifiers: [Int]) async throws -> [WidgetDistance] {
|
||||||
|
identifiers.map { WidgetDistance(id: $0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
func suggestedEntities() async throws -> [WidgetDistance] {
|
||||||
|
FuelStore.stationRadiusOptions.map { WidgetDistance(id: $0) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +78,7 @@ struct FuelBoardWidgetConfigurationIntent: WidgetConfigurationIntent {
|
|||||||
@Parameter(title: "Sort by", default: .cheapest)
|
@Parameter(title: "Sort by", default: .cheapest)
|
||||||
var sort: WidgetSort
|
var sort: WidgetSort
|
||||||
|
|
||||||
@Parameter(title: "Distance", default: .five)
|
@Parameter(title: "Distance", default: WidgetDistance(id: 5))
|
||||||
var distance: WidgetDistance
|
var distance: WidgetDistance
|
||||||
|
|
||||||
/// Edit-Widget UI: the Distance picker only makes sense for Cheapest
|
/// Edit-Widget UI: the Distance picker only makes sense for Cheapest
|
||||||
|
|||||||
Reference in New Issue
Block a user