Skip to content

Commit fddbce0

Browse files
authored
Merge pull request #7872 from woocommerce/issue/7863-widgets-configuration-custom-intent
Widgets Configuration: Add custom intent
2 parents dfae9a9 + a9094a4 commit fddbce0

File tree

7 files changed

+214
-14
lines changed

7 files changed

+214
-14
lines changed

WooCommerce/Resources/Info.plist

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@
7676
<key>NSPhotoLibraryUsageDescription</key>
7777
<string>To save photos from camera for Product images, or to add photos or videos to your Products or support tickets.</string>
7878
<key>NSUserActivityTypes</key>
79-
<array/>
79+
<array>
80+
<string>StoreWidgetsConfigIntent</string>
81+
</array>
8082
<key>UIAppFonts</key>
8183
<array>
8284
<string>Noticons.ttf</string>
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/// Represents the time range for an Order Stats v4 model.
2+
/// This is a local property and not in the remote response.
3+
///
4+
/// - today: hourly data starting midnight today until now.
5+
/// - thisWeek: daily data starting Sunday of this week until now.
6+
/// - thisMonth: daily data starting 1st of this month until now.
7+
/// - thisYear: monthly data starting January of this year until now.
8+
enum StatsTimeRange: String {
9+
case today
10+
case thisWeek
11+
case thisMonth
12+
case thisYear
13+
}
14+
15+
extension StatsTimeRange {
16+
init(_ timeRange: IntentTimeRange) {
17+
switch timeRange {
18+
case .unknown, .today:
19+
self = .today
20+
case .thisWeek:
21+
self = .thisWeek
22+
case .thisMonth:
23+
self = .thisMonth
24+
case .thisYear:
25+
self = .thisYear
26+
}
27+
}
28+
}

WooCommerce/StoreWidgets/StoreInfoDataService.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ final class StoreInfoDataService {
1717
///
1818
private var orderStatsRemoteV4: OrderStatsRemoteV4
1919

20-
/// Visitors remoute source
20+
/// Visitors remote source
2121
///
2222
private var siteVisitStatsRemote: SiteVisitStatsRemote
2323

@@ -31,9 +31,9 @@ final class StoreInfoDataService {
3131
siteVisitStatsRemote = SiteVisitStatsRemote(network: network)
3232
}
3333

34-
/// Async function that fetches todays stats data.
34+
/// Async function that fetches stats data for given time range.
3535
///
36-
func fetchTodayStats(for storeID: Int64) async throws -> Stats {
36+
func fetchStats(for storeID: Int64, timeRange: StatsTimeRange) async throws -> Stats {
3737
// Prepare them to run in parallel
3838
async let revenueAndOrdersRequest = fetchTodaysRevenueAndOrders(for: storeID)
3939
async let visitorsRequest = fetchTodaysVisitors(for: storeID)

WooCommerce/StoreWidgets/StoreInfoProvider.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ struct StoreInfoData {
5656

5757
/// Type that provides data entries to the widget system.
5858
///
59-
final class StoreInfoProvider: TimelineProvider {
59+
final class StoreInfoProvider: IntentTimelineProvider {
6060

6161
/// Holds a reference to the service while a network request is being performed.
6262
///
@@ -75,13 +75,13 @@ final class StoreInfoProvider: TimelineProvider {
7575

7676
/// Quick Snapshot. Required when previewing the widget.
7777
///
78-
func getSnapshot(in context: Context, completion: @escaping (StoreInfoEntry) -> Void) {
78+
func getSnapshot(for configuration: StoreWidgetsConfigIntent, in context: Context, completion: @escaping (StoreInfoEntry) -> Void) {
7979
completion(placeholder(in: context))
8080
}
8181

8282
/// Real data widget.
8383
///
84-
func getTimeline(in context: Context, completion: @escaping (Timeline<StoreInfoEntry>) -> Void) {
84+
func getTimeline(for configuration: StoreWidgetsConfigIntent, in context: Context, completion: @escaping (Timeline<StoreInfoEntry>) -> Void) {
8585
guard let dependencies = Self.fetchDependencies() else {
8686
return completion(Timeline<StoreInfoEntry>(entries: [StoreInfoEntry.notConnected], policy: .never))
8787
}
@@ -90,7 +90,7 @@ final class StoreInfoProvider: TimelineProvider {
9090
networkService = strongService
9191
Task {
9292
do {
93-
let todayStats = try await strongService.fetchTodayStats(for: dependencies.storeID)
93+
let todayStats = try await strongService.fetchStats(for: dependencies.storeID, timeRange: StatsTimeRange(configuration.timeRange))
9494
let entry = Self.dataEntry(for: todayStats, with: dependencies)
9595
let reloadDate = Date(timeIntervalSinceNow: reloadInterval)
9696
let timeline = Timeline<StoreInfoEntry>(entries: [entry], policy: .after(reloadDate))

WooCommerce/StoreWidgets/StoreInfoWidget.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct StoreInfoWidget: Widget {
1818
}
1919

2020
var body: some WidgetConfiguration {
21-
StaticConfiguration(kind: WooConstants.storeInfoWidgetKind, provider: StoreInfoProvider()) { entry in
21+
IntentConfiguration(kind: WooConstants.storeInfoWidgetKind, intent: StoreWidgetsConfigIntent.self, provider: StoreInfoProvider()) { entry in
2222
StoreInfoWidgetEntryView(entry: entry)
2323
}
2424
.configurationDisplayName(Localization.title)

WooCommerce/StoreWidgets/StoreWidgets.intentdefinition

Lines changed: 171 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,185 @@
33
<plist version="1.0">
44
<dict>
55
<key>INEnums</key>
6-
<array/>
6+
<array>
7+
<dict>
8+
<key>INEnumDisplayName</key>
9+
<string>Time Range</string>
10+
<key>INEnumDisplayNameID</key>
11+
<string>pG2KCr</string>
12+
<key>INEnumGeneratesHeader</key>
13+
<true/>
14+
<key>INEnumName</key>
15+
<string>IntentTimeRange</string>
16+
<key>INEnumType</key>
17+
<string>Regular</string>
18+
<key>INEnumValues</key>
19+
<array>
20+
<dict>
21+
<key>INEnumValueDisplayName</key>
22+
<string>unknown</string>
23+
<key>INEnumValueDisplayNameID</key>
24+
<string>whdG6s</string>
25+
<key>INEnumValueName</key>
26+
<string>unknown</string>
27+
</dict>
28+
<dict>
29+
<key>INEnumValueDisplayName</key>
30+
<string>Today</string>
31+
<key>INEnumValueDisplayNameID</key>
32+
<string>Jj2AK7</string>
33+
<key>INEnumValueIndex</key>
34+
<integer>1</integer>
35+
<key>INEnumValueName</key>
36+
<string>today</string>
37+
</dict>
38+
<dict>
39+
<key>INEnumValueDisplayName</key>
40+
<string>This Week</string>
41+
<key>INEnumValueDisplayNameID</key>
42+
<string>jzdldh</string>
43+
<key>INEnumValueIndex</key>
44+
<integer>2</integer>
45+
<key>INEnumValueName</key>
46+
<string>thisWeek</string>
47+
</dict>
48+
<dict>
49+
<key>INEnumValueDisplayName</key>
50+
<string>This Month</string>
51+
<key>INEnumValueDisplayNameID</key>
52+
<string>1HCLUn</string>
53+
<key>INEnumValueIndex</key>
54+
<integer>3</integer>
55+
<key>INEnumValueName</key>
56+
<string>thisMonth</string>
57+
</dict>
58+
<dict>
59+
<key>INEnumValueDisplayName</key>
60+
<string>This Year</string>
61+
<key>INEnumValueDisplayNameID</key>
62+
<string>rkviBd</string>
63+
<key>INEnumValueIndex</key>
64+
<integer>4</integer>
65+
<key>INEnumValueName</key>
66+
<string>thisYear</string>
67+
</dict>
68+
</array>
69+
</dict>
70+
</array>
771
<key>INIntentDefinitionModelVersion</key>
872
<string>1.2</string>
973
<key>INIntentDefinitionNamespace</key>
1074
<string>88xZPY</string>
1175
<key>INIntentDefinitionSystemVersion</key>
12-
<string>21G83</string>
76+
<string>21G115</string>
1377
<key>INIntentDefinitionToolsBuildVersion</key>
14-
<string>13F100</string>
78+
<string>14A309</string>
1579
<key>INIntentDefinitionToolsVersion</key>
16-
<string>13.4.1</string>
80+
<string>14.0</string>
1781
<key>INIntents</key>
18-
<array/>
82+
<array>
83+
<dict>
84+
<key>INIntentCategory</key>
85+
<string>information</string>
86+
<key>INIntentDescriptionID</key>
87+
<string>vsIoMZ</string>
88+
<key>INIntentEligibleForWidgets</key>
89+
<true/>
90+
<key>INIntentIneligibleForSuggestions</key>
91+
<true/>
92+
<key>INIntentLastParameterTag</key>
93+
<integer>2</integer>
94+
<key>INIntentName</key>
95+
<string>StoreWidgetsConfig</string>
96+
<key>INIntentParameters</key>
97+
<array>
98+
<dict>
99+
<key>INIntentParameterConfigurable</key>
100+
<true/>
101+
<key>INIntentParameterDisplayName</key>
102+
<string>Time Range</string>
103+
<key>INIntentParameterDisplayNameID</key>
104+
<string>Piwru2</string>
105+
<key>INIntentParameterDisplayPriority</key>
106+
<integer>1</integer>
107+
<key>INIntentParameterEnumType</key>
108+
<string>IntentTimeRange</string>
109+
<key>INIntentParameterEnumTypeNamespace</key>
110+
<string>88xZPY</string>
111+
<key>INIntentParameterMetadata</key>
112+
<dict>
113+
<key>INIntentParameterMetadataDefaultValue</key>
114+
<string>today</string>
115+
</dict>
116+
<key>INIntentParameterName</key>
117+
<string>timeRange</string>
118+
<key>INIntentParameterPromptDialogs</key>
119+
<array>
120+
<dict>
121+
<key>INIntentParameterPromptDialogCustom</key>
122+
<true/>
123+
<key>INIntentParameterPromptDialogType</key>
124+
<string>Configuration</string>
125+
</dict>
126+
<dict>
127+
<key>INIntentParameterPromptDialogCustom</key>
128+
<true/>
129+
<key>INIntentParameterPromptDialogType</key>
130+
<string>Primary</string>
131+
</dict>
132+
<dict>
133+
<key>INIntentParameterPromptDialogCustom</key>
134+
<true/>
135+
<key>INIntentParameterPromptDialogFormatString</key>
136+
<string>There are ${count} options matching ‘${timeRange}’.</string>
137+
<key>INIntentParameterPromptDialogFormatStringID</key>
138+
<string>8m39ih</string>
139+
<key>INIntentParameterPromptDialogType</key>
140+
<string>DisambiguationIntroduction</string>
141+
</dict>
142+
<dict>
143+
<key>INIntentParameterPromptDialogCustom</key>
144+
<true/>
145+
<key>INIntentParameterPromptDialogFormatString</key>
146+
<string>Just to confirm, you wanted ‘${timeRange}’?</string>
147+
<key>INIntentParameterPromptDialogFormatStringID</key>
148+
<string>SEcvUI</string>
149+
<key>INIntentParameterPromptDialogType</key>
150+
<string>Confirmation</string>
151+
</dict>
152+
</array>
153+
<key>INIntentParameterTag</key>
154+
<integer>2</integer>
155+
<key>INIntentParameterType</key>
156+
<string>Integer</string>
157+
</dict>
158+
</array>
159+
<key>INIntentResponse</key>
160+
<dict>
161+
<key>INIntentResponseCodes</key>
162+
<array>
163+
<dict>
164+
<key>INIntentResponseCodeName</key>
165+
<string>success</string>
166+
<key>INIntentResponseCodeSuccess</key>
167+
<true/>
168+
</dict>
169+
<dict>
170+
<key>INIntentResponseCodeName</key>
171+
<string>failure</string>
172+
</dict>
173+
</array>
174+
</dict>
175+
<key>INIntentTitle</key>
176+
<string>Store Widgets Config</string>
177+
<key>INIntentTitleID</key>
178+
<string>lYFT2L</string>
179+
<key>INIntentType</key>
180+
<string>Custom</string>
181+
<key>INIntentVerb</key>
182+
<string>View</string>
183+
</dict>
184+
</array>
19185
<key>INTypes</key>
20186
<array/>
21187
</dict>

WooCommerce/WooCommerce.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,7 @@
11481148
AEA622B2274669D3002A9B57 /* AddOrderCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA622B1274669D3002A9B57 /* AddOrderCoordinator.swift */; };
11491149
AEA622B427466B78002A9B57 /* BottomSheetOrderType.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA622B327466B78002A9B57 /* BottomSheetOrderType.swift */; };
11501150
AEA622B727468790002A9B57 /* AddOrderCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA622B627468790002A9B57 /* AddOrderCoordinatorTests.swift */; };
1151+
AEA7840428FEE82A000485FC /* StatsTimeRange.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEA7840328FEE82A000485FC /* StatsTimeRange.swift */; };
11511152
AEACCB6D2785FF4A000D01F0 /* NavigationRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEACCB6C2785FF4A000D01F0 /* NavigationRow.swift */; };
11521153
AEB73C0C25CD734200A8454A /* AttributePickerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEB73C0B25CD734200A8454A /* AttributePickerViewModel.swift */; };
11531154
AEB73C1725CD8E5800A8454A /* AttributePickerViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEB73C1625CD8E5800A8454A /* AttributePickerViewModelTests.swift */; };
@@ -3046,6 +3047,7 @@
30463047
AEA622B1274669D3002A9B57 /* AddOrderCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOrderCoordinator.swift; sourceTree = "<group>"; };
30473048
AEA622B327466B78002A9B57 /* BottomSheetOrderType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BottomSheetOrderType.swift; sourceTree = "<group>"; };
30483049
AEA622B627468790002A9B57 /* AddOrderCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddOrderCoordinatorTests.swift; sourceTree = "<group>"; };
3050+
AEA7840328FEE82A000485FC /* StatsTimeRange.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatsTimeRange.swift; sourceTree = "<group>"; };
30493051
AEACCB6C2785FF4A000D01F0 /* NavigationRow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationRow.swift; sourceTree = "<group>"; };
30503052
AEB73C0B25CD734200A8454A /* AttributePickerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributePickerViewModel.swift; sourceTree = "<group>"; };
30513053
AEB73C1625CD8E5800A8454A /* AttributePickerViewModelTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributePickerViewModelTests.swift; sourceTree = "<group>"; };
@@ -5378,6 +5380,7 @@
53785380
265C99E028B9BA43005E6117 /* StoreInfoWidget.swift */,
53795381
265C99E328B9C834005E6117 /* StoreInfoProvider.swift */,
53805382
260DE20828CA7CE2009ECD7C /* StoreInfoDataService.swift */,
5383+
AEA7840328FEE82A000485FC /* StatsTimeRange.swift */,
53815384
265C99E528B9CB8E005E6117 /* StoreInfoViewModifiers.swift */,
53825385
3F1FA84728B60125009E246C /* StoreWidgets.intentdefinition */,
53835386
3F1FA84828B60126009E246C /* Assets.xcassets */,
@@ -9395,6 +9398,7 @@
93959398
AED9012D28E5F517002B4572 /* AppLinkWidget.swift in Sources */,
93969399
2608C50728C941D600C9DFC0 /* UserDefaults+Woo.swift in Sources */,
93979400
265C99E628B9CB8E005E6117 /* StoreInfoViewModifiers.swift in Sources */,
9401+
AEA7840428FEE82A000485FC /* StatsTimeRange.swift in Sources */,
93989402
2608C50628C93AB700C9DFC0 /* WooConstants.swift in Sources */,
93999403
260DE20A28CA7CFE009ECD7C /* StoreInfoDataService.swift in Sources */,
94009404
AE56E73428E76CDB00A1292B /* StoreInfoInlineWidget.swift in Sources */,

0 commit comments

Comments
 (0)