Widget config sheet: revert WidgetSort to String-backed AppEnum. parameterSummary When(\.$sort, .equalTo, …) silently falls back to the otherwise branch for AppEntity parameters (iOS 17+ bug FB13263902), which hid the Favourite/Favourite Fuel rows on the small widget — the metadata compared against a literal 'WidgetSort.favourites' string instead of the enum case. String AppEnums match reliably (the d8506a0 form). Tradeoff: the Sort picker always offers Favourites; picking it with no favourites shows the empty state. FavouriteFuel entity + IntentParameterDependency filtering unchanged.
This commit is contained in:
@@ -21,48 +21,24 @@ enum WidgetFuel: String, AppEnum, CaseIterable, Codable {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per-widget sort order. Modelled as an AppEntity (not an AppEnum) so the
|
// Per-widget sort order. A String-backed AppEnum (NOT an AppEntity): the
|
||||||
// options can be dynamic: "Favourites" only appears when the user actually
|
// parameterSummary conditionals (When(\.$sort, .equalTo, …)) fall back to the
|
||||||
// has favourites — an empty favourite list makes the option dead weight.
|
// otherwise branch for AppEntity parameters (iOS 17+ bug FB13263902), which
|
||||||
struct WidgetSort: AppEntity, Identifiable, Hashable, Codable {
|
// hid the Favourite picker. String AppEnums match reliably. Tradeoff: the
|
||||||
enum Kind: String, Codable {
|
// option set is static — "Favourites" always appears, and picking it with no
|
||||||
|
// favourites shows the empty state.
|
||||||
|
enum WidgetSort: String, AppEnum, CaseIterable, Codable {
|
||||||
case cheapest
|
case cheapest
|
||||||
case closest
|
case closest
|
||||||
case favourites
|
case favourites
|
||||||
}
|
|
||||||
|
|
||||||
let id: String
|
|
||||||
|
|
||||||
var kind: Kind { Kind(rawValue: id) ?? .cheapest }
|
|
||||||
|
|
||||||
static let cheapest = WidgetSort(id: "cheapest")
|
|
||||||
static let closest = WidgetSort(id: "closest")
|
|
||||||
static let favourites = WidgetSort(id: "favourites")
|
|
||||||
|
|
||||||
var displayRepresentation: DisplayRepresentation {
|
|
||||||
switch kind {
|
|
||||||
case .cheapest: return DisplayRepresentation(stringLiteral: "Cheapest")
|
|
||||||
case .closest: return DisplayRepresentation(stringLiteral: "Closest")
|
|
||||||
case .favourites: return DisplayRepresentation(stringLiteral: "Favourites")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Sort by"
|
static var typeDisplayRepresentation: TypeDisplayRepresentation = "Sort by"
|
||||||
static var defaultQuery = WidgetSortQuery()
|
|
||||||
}
|
|
||||||
|
|
||||||
struct WidgetSortQuery: EntityQuery {
|
static var caseDisplayRepresentations: [WidgetSort: DisplayRepresentation] = [
|
||||||
func entities(for identifiers: [String]) async throws -> [WidgetSort] {
|
.cheapest: "Cheapest",
|
||||||
identifiers.map { WidgetSort(id: $0) }
|
.closest: "Closest",
|
||||||
}
|
.favourites: "Favourites",
|
||||||
|
]
|
||||||
func suggestedEntities() async throws -> [WidgetSort] {
|
|
||||||
var sorts = [WidgetSort.cheapest, WidgetSort.closest]
|
|
||||||
if !FuelStore.loadFavourites().isEmpty {
|
|
||||||
sorts.append(.favourites)
|
|
||||||
}
|
|
||||||
return sorts
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per-widget distance filter. Modelled as an AppEntity (not an AppEnum) so
|
// Per-widget distance filter. Modelled as an AppEntity (not an AppEnum) so
|
||||||
|
|||||||
Reference in New Issue
Block a user