Widget gallery order + default-widget skeleton fix. (1) Register FuelPriceSmallWidget BEFORE FuelPriceWidget so the gallery lists small, then medium (bundle order = gallery order). (2) Revert entity resolution to LENIENT: the timeline request resolves the full configuration through the entity queries, and the b1765b5 strict entities(for:) (nil for the empty default favourite 'fuel|') failed resolution for default-config small widgets, stranding them on the iOS skeleton placeholder. entities(for:) now always returns a value; defaultResult() still auto-populates fresh widgets to the first fuel with a favourite / first favourite of that fuel.
This commit is contained in:
@@ -4,8 +4,9 @@ import SwiftUI
|
|||||||
@main
|
@main
|
||||||
struct FuelBoardWidgetsBundle: WidgetBundle {
|
struct FuelBoardWidgetsBundle: WidgetBundle {
|
||||||
var body: some Widget {
|
var body: some Widget {
|
||||||
FuelPriceWidget()
|
// Gallery order follows registration order: small first, then medium.
|
||||||
FuelPriceSmallWidget()
|
FuelPriceSmallWidget()
|
||||||
|
FuelPriceWidget()
|
||||||
FuelBoardLiveActivity()
|
FuelBoardLiveActivity()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,16 +92,14 @@ struct FavouriteFuel: AppEntity, Identifiable, Hashable, Codable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct FavouriteFuelQuery: EntityQuery {
|
struct FavouriteFuelQuery: EntityQuery {
|
||||||
/// Strict: a fuel only resolves if it ACTUALLY has favourites. A stored
|
// LENIENT resolution: every valid fuel resolves, even one without
|
||||||
/// value for a fuel that lost all its favourites (or the static .e10
|
// favourites. The timeline request resolves the FULL configuration
|
||||||
/// default on a fresh widget) fails resolution and falls back to
|
// through these queries, and a nil result fails the whole timeline — a
|
||||||
/// defaultResult() — the first fuel that has a favourite.
|
// default-config widget would hang on the skeleton placeholder. Fresh
|
||||||
|
// widgets still auto-populate via defaultResult(); the picker options
|
||||||
|
// stay filtered in suggestedEntities().
|
||||||
func entities(for identifiers: [String]) async throws -> [FavouriteFuel] {
|
func entities(for identifiers: [String]) async throws -> [FavouriteFuel] {
|
||||||
let fuels = Set(FuelStore.loadFavourites().map(\.fuel))
|
identifiers.compactMap { FuelType(rawValue: $0) }.map { FavouriteFuel(fuel: $0) }
|
||||||
return identifiers.compactMap { id in
|
|
||||||
guard let fuel = FuelType(rawValue: id), fuels.contains(fuel) else { return nil }
|
|
||||||
return FavouriteFuel(fuel: fuel)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func suggestedEntities() async throws -> [FavouriteFuel] {
|
func suggestedEntities() async throws -> [FavouriteFuel] {
|
||||||
@@ -162,18 +160,22 @@ struct WidgetFavouriteQuery: EntityQuery {
|
|||||||
)
|
)
|
||||||
var smallIntent
|
var smallIntent
|
||||||
|
|
||||||
|
// LENIENT resolution: every stored identifier resolves to a
|
||||||
|
// WidgetFavourite (best-effort name lookup). NEVER return nil here — the
|
||||||
|
// timeline request resolves the whole configuration through this query
|
||||||
|
// and a failed resolution strands a default-config widget on the skeleton
|
||||||
|
// placeholder. Fresh widgets auto-populate via defaultResult().
|
||||||
func entities(for identifiers: [String]) async throws -> [WidgetFavourite] {
|
func entities(for identifiers: [String]) async throws -> [WidgetFavourite] {
|
||||||
let favourites = FuelStore.loadFavourites()
|
let favourites = FuelStore.loadFavourites()
|
||||||
return identifiers.compactMap { id in
|
return identifiers.map { id in
|
||||||
// Strict: only real, existing favourites resolve. The empty
|
let parts = id.split(separator: "|", maxSplits: 1)
|
||||||
// static default (id "fuel|") and removed favourites fail
|
let fuel = FuelType(rawValue: String(parts.first ?? "")) ?? .e10
|
||||||
// resolution so the sheet falls back to defaultResult().
|
let stationID = String(parts.last ?? "")
|
||||||
guard !id.hasSuffix("|"),
|
let entry = favourites.first { $0.id == id }
|
||||||
let entry = favourites.first(where: { $0.id == id }) else { return nil }
|
|
||||||
return WidgetFavourite(
|
return WidgetFavourite(
|
||||||
fuel: entry.fuel,
|
fuel: fuel,
|
||||||
stationID: entry.station.id,
|
stationID: stationID,
|
||||||
stationName: entry.station.name
|
stationName: entry?.station.name ?? ""
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user