Widgets: merge small+medium into one kind (both sizes, one gallery entry)
This commit is contained in:
@@ -17,13 +17,14 @@ private extension FuelType {
|
||||
}
|
||||
}
|
||||
|
||||
// FuelBoard widget — petrol stations near you.
|
||||
// FuelPriceWidget (medium): top 3 stations with price + distance, each row
|
||||
// opens Maps. Per-widget fuel + sort (+ distance for Cheapest).
|
||||
// FuelPriceSmallWidget (small): single station, whole widget opens Maps.
|
||||
// Same knobs as the medium — the small face shows the first of the
|
||||
// configured result (cheapest/closest station, or the cheapest favourite
|
||||
// of the chosen fuel in Favourites mode).
|
||||
// FuelBoard widget — petrol stations near you. ONE widget kind, TWO sizes:
|
||||
// .systemSmall: single station (the first of the configured result — the
|
||||
// cheapest/closest station, or the cheapest favourite of the chosen fuel
|
||||
// in Favourites mode); the whole face opens Maps.
|
||||
// .systemMedium: top 3 stations with price + distance, each row opens Maps.
|
||||
// Per-widget fuel + sort (+ distance for Cheapest) via one config intent.
|
||||
// The view branches on widgetFamily, not kind — the small face renders the
|
||||
// first station, the medium face the list.
|
||||
// Taps deep-link to Apple Maps directions (maps://?daddr=). On the Home
|
||||
// Screen the system either opens Maps directly or delivers the URL to
|
||||
// FuelBoard, whose onOpenURL forwards it (and also still handles legacy
|
||||
@@ -49,6 +50,13 @@ private extension FuelType {
|
||||
// (no permission yet / timeout) it falls back to the app's cached location,
|
||||
// then to price-only sorting. So the widget is location-driven the moment the
|
||||
// app has been opened once and permission granted.
|
||||
//
|
||||
// History: a separate "small" kind existed (FuelPriceWidgetSmall) and was
|
||||
// merged here on 2026-08-14. The small kind had gained .systemMedium so the
|
||||
// iOS long-press app-icon menu (which shows only the FIRST-registered kind's
|
||||
// sizes) would offer both tiles — but that duplicated the medium gallery
|
||||
// entry. Merging keeps both size tiles in the icon menu AND one gallery entry
|
||||
// with both sizes.
|
||||
|
||||
struct FuelPriceWidget: Widget {
|
||||
let kind = "FuelPriceWidget"
|
||||
@@ -70,49 +78,8 @@ struct FuelPriceWidget: Widget {
|
||||
}
|
||||
.configurationDisplayName("FuelBoard Prices")
|
||||
.description("Fuel prices near you. Configure fuel + sort per widget.")
|
||||
.supportedFamilies([.systemMedium])
|
||||
.disfavoredLocations([.carPlay], for: [.systemMedium])
|
||||
}
|
||||
}
|
||||
|
||||
// Small widget — exactly ONE station (the first of the configured result)
|
||||
// when rendered at systemSmall; the SAME kind also supports .systemMedium,
|
||||
// where the shared view renders the station list (identical content to the
|
||||
// medium widget — the view branches on family, not kind).
|
||||
//
|
||||
// WHY medium is here (2026-08-14): the iOS 18+ long-press app-icon menu
|
||||
// ("turn app icon into a widget") shows the supported SIZES of the
|
||||
// FIRST-registered widget kind only — it does NOT list widget kinds, and it
|
||||
// is NOT keyed by configuration-intent type (a two-intent experiment,
|
||||
// 6375af4, changed nothing on-device). So the bundle's first kind decides
|
||||
// which size tiles the icon menu offers: small-only meant the menu showed
|
||||
// only the small tile even though the app has a medium widget. Giving this
|
||||
// first-registered kind BOTH .systemSmall and .systemMedium puts both size
|
||||
// tiles in the icon menu (ChatGPT/Safari show multiple sizes the same way —
|
||||
// their first kind supports several families). The gallery still lists both
|
||||
// widget kinds in bundle order (small, then medium); this kind's entry just
|
||||
// gains a medium variant. Favourites sort on the small face shows the
|
||||
// cheapest favourite of the chosen fuel.
|
||||
struct FuelPriceSmallWidget: Widget {
|
||||
let kind = "FuelPriceWidgetSmall"
|
||||
|
||||
var body: some WidgetConfiguration {
|
||||
AppIntentConfiguration(
|
||||
kind: kind,
|
||||
intent: FuelBoardSmallWidgetConfigurationIntent.self,
|
||||
provider: FuelPriceTimelineProvider<FuelBoardSmallWidgetConfigurationIntent>(
|
||||
beaconTag: "FuelBoardSmallWidget"
|
||||
)
|
||||
) { entry in
|
||||
FuelPriceWidgetView(entry: entry)
|
||||
.containerBackground(for: .widget) {
|
||||
Color(.systemBackground)
|
||||
}
|
||||
}
|
||||
.configurationDisplayName("FuelBoard Small")
|
||||
.description("Fuel prices near you. Configure fuel + sort per widget.")
|
||||
.supportedFamilies([.systemSmall, .systemMedium])
|
||||
.disfavoredLocations([.carPlay], for: [.systemSmall])
|
||||
.disfavoredLocations([.carPlay], for: [.systemSmall, .systemMedium])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,7 +217,7 @@ struct FuelPriceTimelineProvider<Configuration: WidgetConfigurationIntent & Widg
|
||||
// the cheapest favourite of the chosen fuel. (The old per-widget
|
||||
// pinned-favourite picker was removed: its AppEntity params made
|
||||
// fresh-widget default-config resolution fail at the system level
|
||||
// — see FuelPriceSmallWidget.)
|
||||
// — the merged widget uses the minimal fuel/sort/distance intent.)
|
||||
let fuelFavourites = favourites
|
||||
.filter { $0.fuel == fuel && $0.station.prices[fuel] != nil }
|
||||
.map(\.station)
|
||||
|
||||
Reference in New Issue
Block a user