From 3dd567a5ccfc6046d6af441088519822ffc11e06 Mon Sep 17 00:00:00 2001 From: FuelBoard Contributor Date: Fri, 14 Aug 2026 09:52:50 +0100 Subject: [PATCH] Widgets: merge small+medium into one kind (both sizes, one gallery entry) --- FuelBoardWidgets/FuelBoardWidgetsBundle.swift | 5 +- FuelBoardWidgets/FuelPriceWidget.swift | 67 +++++-------------- FuelBoardWidgets/WidgetConfigIntent.swift | 48 ------------- 3 files changed, 20 insertions(+), 100 deletions(-) diff --git a/FuelBoardWidgets/FuelBoardWidgetsBundle.swift b/FuelBoardWidgets/FuelBoardWidgetsBundle.swift index e38f95e..83a8d26 100644 --- a/FuelBoardWidgets/FuelBoardWidgetsBundle.swift +++ b/FuelBoardWidgets/FuelBoardWidgetsBundle.swift @@ -4,8 +4,9 @@ import SwiftUI @main struct FuelBoardWidgetsBundle: WidgetBundle { var body: some Widget { - // Gallery order follows registration order: small first, then medium. - FuelPriceSmallWidget() + // ONE widget kind (both sizes) first — the iOS long-press app-icon + // menu shows the FIRST-registered kind's sizes; this kind supports + // .systemSmall + .systemMedium so both tiles appear. FuelPriceWidget() FuelBoardLiveActivity() } diff --git a/FuelBoardWidgets/FuelPriceWidget.swift b/FuelBoardWidgets/FuelPriceWidget.swift index 6d82b65..6df13d7 100644 --- a/FuelBoardWidgets/FuelPriceWidget.swift +++ b/FuelBoardWidgets/FuelPriceWidget.swift @@ -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( - 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