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 {
|
||||
case five
|
||||
case ten
|
||||
case fifteen
|
||||
// Per-widget distance filter. Modelled as an AppEntity (not an AppEnum) so
|
||||
// the option labels can mirror the app's units setting at render time: an
|
||||
// AppEnum's caseDisplayRepresentations are STATIC, so the Edit-Widget picker
|
||||
// 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 {
|
||||
let unit = FuelStore.loadDistanceUnit()
|
||||
let shown = unit.displayMiles(miles)
|
||||
let shown = unit.displayMiles(id)
|
||||
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
|
||||
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Distance"
|
||||
static var defaultQuery = WidgetDistanceQuery()
|
||||
}
|
||||
|
||||
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)
|
||||
var sort: WidgetSort
|
||||
|
||||
@Parameter(title: "Distance", default: .five)
|
||||
@Parameter(title: "Distance", default: WidgetDistance(id: 5))
|
||||
var distance: WidgetDistance
|
||||
|
||||
/// Edit-Widget UI: the Distance picker only makes sense for Cheapest
|
||||
|
||||
Reference in New Issue
Block a user